diff --git a/CHANGES b/CHANGES
deleted file mode 100644
--- a/CHANGES
+++ /dev/null
@@ -1,613 +0,0 @@
-Developer-ish changes in the hledger-lib package.
-User-visible changes are noted in the hledger package changelog instead.
-
-
-# 1.12 (2018/12/02)
-
-* switch to megaparsec 7 (Alex Chen)
-  We now track the stack of include files in Journal ourselves, since
-  megaparsec dropped this feature.
-
-* add 'ExceptT' layer to our parser monad again (Alex Chen)
-  We previously had a parser type, 'type ErroringJournalParser = ExceptT
-  String ...' for throwing parse errors without allowing further
-  backtracking. This parser type was removed under the assumption that it
-  would be possible to write our parser without this capability. However,
-  after a hairy backtracking bug, we would now prefer to have the option to
-  prevent backtracking.
-
-  - Define a 'FinalParseError' type specifically for the 'ExceptT' layer
-  - Any parse error can be raised as a "final" parse error
-  - Tracks the stack of include files for parser errors, anticipating the
-    removal of the tracking of stacks of include files in megaparsec 7
-    - Although a stack of include files is also tracked in the 'StateT
-      Journal' layer of the parser, it seems easier to guarantee correct
-      error messages in the 'ExceptT FinalParserError' layer
-    - This does not make the 'StateT Journal' stack redundant because the
-      'ExceptT FinalParseError' stack cannot be used to detect cycles of
-      include files
-
-* more support for location-aware parse errors when re-parsing (Alex Chen)
-
-* make 'includedirectivep' an 'ErroringJournalParser' (Alex Chen)
-
-* drop Ord instance breaking GHC 8.6 build (Peter Simons)
-
-* flip the arguments of (divide|multiply)[Mixed]Amount
-
-* showTransaction: fix a case showing multiple missing amounts
-  showTransaction could sometimes hide the last posting's amount even if
-  one of the other posting amounts was already implcit, producing invalid
-  transaction output.
-
-* plog, plogAt: add missing newline
-
-* split up journalFinalise, reorder journal finalisation steps (#893) (Jesse Rosenthal)
-  The `journalFinalise` function has been split up, allowing more granular
-  control.
-
-* journalSetTime --> journalSetLastReadTime
-
-* journalSetFilePath has been removed, use journalAddFile instead
-
-
-# 1.11.1 (2018/10/06)
-
-* add, lib: fix wrong transaction rendering in balance assertion errors
-  and when using the add command
-
-# 1.11 (2018/9/30)
-
-* compilation now works when locale is unset (#849)
-
-* all unit tests have been converted from HUnit+test-framework to easytest
-
-* doctests now run quicker by default, by skipping reloading between tests. 
-  This can be disabled by passing --slow to the doctests test suite
-  executable.
-
-* doctests test suite executable now supports --verbose, which shows
-  progress output as tests are run if doctest 0.16.0+ is installed
-  (and hopefully is harmless otherwise).
-
-* doctests now support file pattern arguments, provide more informative output.
-  Limiting to just the file(s) you're interested can make doctest start
-  much quicker. With one big caveat: you can limit the starting files,
-  but it always imports and tests all other local files those import.
-
-* a bunch of custom Show instances have been replaced with defaults,
-  for easier troubleshooting.  These were sometimes obscuring
-  important details, eg in test failure output. Our new policy is:
-  stick with default derived Show instances as far as possible, but
-  when necessary adjust them to valid haskell syntax so pretty-show
-  can pretty-print them (eg when they contain Day values, cf
-  https://github.com/haskell/time/issues/101).  By convention, when
-  fields are shown in less than full detail, and/or in double-quoted
-  pseudo syntax, we show a double period (..) in the output.
-
-* Amount has a new Show instance.  Amount's show instance hid
-  important details by default, and showing more details required
-  increasing the debug level, which was inconvenient.  Now it has a
-  single show instance which shows more information, is fairly
-  compact, and is pretty-printable.
-
-  ghci> usd 1
-  OLD:
-  Amount {acommodity="$", aquantity=1.00, ..}
-  NEW:
-  Amount {acommodity = "$", aquantity = 1.00, aprice = NoPrice, astyle = AmountStyle "L False 2 Just '.' Nothing..", amultiplier = False}
-
-  MixedAmount's show instance is unchanged, but showMixedAmountDebug
-  is affected by this change:
-
-  ghci> putStrLn $ showMixedAmountDebug $ Mixed [usd 1]
-  OLD:
-  Mixed [Amount {acommodity="$", aquantity=1.00, aprice=, astyle=AmountStyle {ascommodityside = L, ascommodityspaced = False, asprecision = 2, asdecimalpoint = Just '.', asdigitgroups = Nothing}}]
-  NEW:
-  Mixed [Amount {acommodity="$", aquantity=1.00, aprice=, astyle=AmountStyle "L False 2 Just '.' Nothing.."}]
-
-* Same-line & next-line comments of transactions, postings, etc.
-  are now parsed a bit more precisely (followingcommentp). 
-  Previously, parsing no comment gave the same result as an empty
-  comment (a single newline); now it gives an empty string.  
-  Also, and perhaps as a consequence of the above, when there's no
-  same-line comment but there is a next-line comment, we'll insert an
-  empty first line, since otherwise next-line comments would get moved
-  up to the same line when rendered.
-
-* Hledger.Utils.Test exports HasCallStack
-
-* queryDateSpan, queryDateSpan' now intersect date AND'ed date spans
-  instead of unioning them, and docs are clearer.
-
-* pushAccount -> pushDeclaredAccount
-
-* jaccounts -> jdeclaredaccounts
-
-* AutoTransaction.hs -> PeriodicTransaction.hs & TransactionModifier.hs
-
-* Hledger.Utils.Debug helpers have been renamed/cleaned up
-
-
-# 1.10 (2018/6/30)
-
-* build cleanly with all supported GHC versions again (7.10 to 8.4)
-
-* support/use latest base-compat (#794)
-
-* support/require megaparsec 6.4+
-
-* extensive refactoring and cleanup of parsers and related types and utilities
-
-* readJournalFile(s) cleanup, these now use InputOpts
-
-* doctests now run a bit faster (#802)
-
-
-# 1.9.1 (2018/4/30)
-
-* new generic PeriodicReport, and some report-related type aliases
-
-* new BudgetReport
-
-* make (readJournal|tryReader)s?WithOpts the default api, dropping "WithOpts"
-
-* automated postings and command line account aliases happen earlier
-  in journal processing (see hledger changelog)
-
-
-# 1.9 (2018/3/31)
-
-* support ghc 8.4, latest deps
-
-* when the system text encoding is UTF-8, ignore any UTF-8 BOM prefix
-found when reading files.
-
-* CompoundBalanceReport amounts are now normally positive.
-The bs/bse/cf/is commands now show normal income, liability and equity
-balances as positive.  Negative numbers now indicate a contra-balance
-(eg an overdrawn checking account), a net loss, a negative net worth,
-etc.  This makes these reports more like conventional financial
-statements, and easier to read and share with others. (experimental)
-
-* splitSpan now returns no spans for an empty datespan
-
-* don't count periodic/modifier txns in Journal debug output
-
-* lib/ui/web/api: move embedded manual files to extra-source-files
-
-* Use skipMany/skipSome for parsing spacenonewline (Moritz Kiefer)
-This avoids allocating the list of space characters only to then
-discard it.
-
-* rename, clarify purpose of balanceReportFromMultiBalanceReport
-
-* fix some hlint warnings
-
-* add some easytest tests
-
-
-# 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)
-
-* add readJournalFile[s]WithOpts, with simpler arguments and support
-for detecting new transactions since the last read.
-
-* query: add payee: and note: query terms, improve description/payee/note docs (Jakub Zárybnický, Simon Michael, #598, #608)
-
-* journal, cli: make trailing whitespace significant in regex account aliases
-Trailing whitespace in the replacement part of a regular expression
-account alias is now significant. Eg, converting a parent account to
-just an account name prefix: --alias '/:acct:/=:acct '
-
-* timedot: allow a quantity of seconds, minutes, days, weeks, months
-  or years to be logged as Ns, Nm, Nd, Nw, Nmo, Ny
-
-* csv: switch the order of generated postings, so account1 is first.
-This simplifies things and facilitates future improvements.
-
-* csv: show the "creating/using rules file" message only with --debug
-
-* csv: fix multiple includes in one rules file
-
-* csv: add "newest-first" rule for more robust same-day ordering
-
-* deps: allow ansi-terminal 0.7
-
-* deps: add missing parsec lower bound, possibly related to #596, fpco/stackage#2835
-
-* deps: drop oldtime flag, require time 1.5+
-
-* deps: remove ghc < 7.6 support, remove obsolete CPP conditionals
-
-* deps: fix test suite with ghc 8.2
-
-
-# 1.3.1 (2017/8/25)
-
-* Fix a bug with -H showing nothing for empty periods (#583, Nicholas Niro)
-This patch fixes a bug that happened when using the -H option on
-a period without any transaction. Previously, the behavior was no
-output at all even though it should have shown the previous ending balances
-of past transactions. (This is similar to previously using -H with -E,
-but with the extra advantage of not showing empty accounts)
-
-* allow megaparsec 6 (#594)
-
-* allow megaparsec-6.1 (Hans-Peter Deifel)
-
-* fix test suite with Cabal 2 (#596)
-
-
-# 1.3 (2017/6/30)
-
-journal: The "uncleared" transaction/posting status, and associated UI flags
-and keys, have been renamed to "unmarked" to remove ambiguity and
-confusion.  This means that we have dropped the `--uncleared` flag,
-and our `-U` flag now matches only unmarked things and not pending
-ones.  See the issue and linked mail list discussion for more
-background.  (#564)
-
-csv: assigning to the "balance" field name creates balance
-assertions (#537, Dmitry Astapov).
-
-csv: Doubled minus signs are handled more robustly (fixes #524, Nicolas Wavrant, Simon Michael)
-
-Multiple "status:" query terms are now OR'd together. (#564)
-
-deps: allow megaparsec 5.3.
-
-
-# 1.2 (2017/3/31)
-
-## journal format
-
-A pipe character can optionally be used to delimit payee names in
-transaction descriptions, for more accurate querying and pivoting by
-payee.  Eg, for a description like `payee name | additional notes`,
-the two parts will be accessible as pseudo-fields/tags named `payee`
-and `note`.
-
-Some journal parse errors now show the range of lines involved, not just the first.
-
-## ledger format
-
-The experimental `ledger:` reader based on the WIP ledger4 project has
-been disabled, reducing build dependencies.
-
-## Misc
-
-Fix a bug when tying the knot between postings and their parent transaction, reducing memory usage by about 10% (#483) (Mykola Orliuk)
-
-Fix a few spaceleaks (#413) (Moritz Kiefer)
-
-Add Ledger.Parse.Text to package.yaml, fixing a potential build failure.
-
-Allow megaparsec 5.2 (#503)
-
-Rename optserror -> usageError, consolidate with other error functions
-
-
-# 1.1 (2016/12/31)
-
-## journal format
-
--   balance assignments are now supported (#438, #129, #157, #288)
-
-    This feature also brings a slight performance drop (~5%);
-    optimisations welcome.
-
--   also recognise `*.hledger` files as hledger journal format
-
-## ledger format
-
--   use ledger-parse from the ledger4 project as an alternate reader for C++ Ledger journals
-    
-    The idea is that some day we might get better compatibility with Ledger files this way.
-    Right now this reader is not very useful and will be used only if you explicitly select it with a `ledger:` prefix.
-    It parses transaction dates, descriptions, accounts and amounts, and ignores everything else.
-    Amount parsing is delegated to hledger's journal parser, and malformed amounts might be silently ignored.
-
-    This adds at least some of the following as new dependencies for hledger-lib:
-    parsers, parsec, attoparsec, trifecta.
-
-## misc
-
--   update base lower bound to enforce GHC 7.10+
-    
-    hledger-lib had a valid install plan with GHC 7.8, but currently requires GHC 7.10 to compile.
-    Now we require base 4.8+ everywhere to ensure the right GHC version at the start.
-    
--   Hledger.Read api cleanups
-
--   rename dbgIO to dbg0IO, consistent with dbg0, and document a bug in dbg*IO
-
--   make readJournalFiles [f] equivalent to readJournalFile f (#437)
-
--   more general parser types enabling reuse outside of IO (#439)
-
-
-# 1.0.1 (2016/10/27)
-
-- allow megaparsec 5.0 or 5.1
-
-
-# 1.0 (2016/10/26)
-
-## timedot format
-
--   new "timedot" format for retroactive/approximate time logging.
-
-    Timedot is a plain text format for logging dated, categorised
-    quantities (eg time), 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.
-
-## timeclock format
-
--   renamed "timelog" format to "timeclock", matching the emacs package
-
--   sessions can no longer span file boundaries (unclocked-out
-
-    sessions will be auto-closed at the end of the file).
-
--   transaction ids now count up rather than down (#394)
-
--   timeclock files no longer support default year directives
-
--   removed old code for appending timeclock transactions to journal transactions.
-
-    A holdover from the days when both were allowed in one file.
-
-## csv format
-
--   fix empty field assignment parsing, rule parse errors after megaparsec port (#407) (Hans-Peter Deifel)
-
-## journal format
-
--   journal files can now include timeclock or timedot files (#320)
-
-    (but not yet CSV files).
-
--   fixed an issue with ordering of same-date transactions included from other files
-
--   the "commodity" directive and "format" subdirective are now supported, allowing
-
-    full control of commodity style (#295) The commodity directive's
-    format subdirective can now be used to override the inferred
-    style for a commodity, eg to increase or decrease the
-    precision. This is at least a good workaround for #295.
-
--   Ledger-style "apply account"/"end apply account" directives are now used to set a default parent account.
-
--   the Ledger-style "account" directive is now accepted (and ignored).
-
--   bracketed posting dates are more robust (#304)
-
-    Bracketed posting dates were fragile; they worked only if you
-    wrote full 10-character dates. Also some semantics were a bit
-    unclear. Now they should be robust, and have been documented
-    more clearly. This is a legacy undocumented Ledger syntax, but
-    it improves compatibility and might be preferable to the more
-    verbose "date:" tags if you write posting dates often (as I do).
-    Internally, bracketed posting dates are no longer considered to
-    be tags.  Journal comment, tag, and posting date parsers have
-    been reworked, all with doctests.
-
--   balance assertion failure messages are clearer
-
--   with --debug=2, more detail about balance assertions is shown.
-
-## misc
-
--   file parsers have been ported from Parsec to Megaparsec \o/ (#289, #366) (Alexey Shmalko, Moritz Kiefer)
-
--   most hledger types have been converted from String to Text, reducing memory usage by 30%+ on large files
-
--   file parsers have been simplified for easier troubleshooting (#275).
-
-    The journal/timeclock/timedot parsers, instead of constructing
-    opaque journal update functions which are later applied to build
-    the journal, now construct the journal directly by modifying the
-    parser state. This is easier to understand and debug. It also
-    rules out the possibility of journal updates being a space
-    leak. (They weren't, in fact this change increased memory usage
-    slightly, but that has been addressed in other ways).  The
-    ParsedJournal type alias has been added to distinguish
-    "being-parsed" journals and "finalised" journals.
-
--   file format detection is more robust.
-
-    The Journal, Timelog and Timedot readers' detectors now check
-    each line in the sample data, not just the first one. I think the
-    sample data is only about 30 chars right now, but even so this
-    fixed a format detection issue I was seeing. 
-    Also, we now always try parsing stdin as journal format (not just sometimes).
-
--   all file formats now produce transaction ids, not just journal (#394)
-
--   git clone of the hledger repo on windows now works (#345)
-
--   added missing benchmark file (#342)
-
--   our stack.yaml files are more compatible across stack versions (#300)
-
--   use newer file-embed to fix ghci working directory dependence (<https://github.com/snoyberg/file-embed/issues/18>)
-
--   report more accurate dates in account transaction report when postings have their own dates
-
-    (affects hledger-ui and hledger-web registers).
-    The newly-named "transaction register date" is the date to be
-    displayed for that transaction in a transaction register, for
-    some current account and filter query.  It is either the
-    transaction date from the journal ("transaction general date"),
-    or if postings to the current account and matched by the
-    register's filter query have their own dates, the earliest of
-    those posting dates.
-
--   simplify account transactions report's running total.
-
-    The account transactions report used for hledger-ui and -web
-    registers now gives either the "period total" or "historical
-    total", depending strictly on the --historical flag. It doesn't
-    try to indicate whether the historical total is the accurate
-    historical balance (which depends on the user's report query).
-
--   reloading a file now preserves the effect of options, query arguments etc.
-
--   reloading a journal should now reload all included files as well.
-
--   the Hledger.Read.\* modules have been reorganised for better reuse.
-
-    Hledger.Read.Utils has been renamed Hledger.Read.Common
-    and holds low-level parsers & utilities; high-level read
-    utilities are now in Hledger.Read.
-
--   clarify amount display style canonicalisation code and terminology a bit.
-
-    Individual amounts still have styles; from these we derive
-    the standard "commodity styles". In user docs, we might call
-    these "commodity formats" since they can be controlled by the
-    "format" subdirective in journal files.
-
--   Journal is now a monoid
-
--   expandPath now throws a proper IO error
-
--   more unit tests, start using doctest
-
-
-
-
-0.27 (2015/10/30)
-
-- The main hledger types now derive NFData, which makes it easier to
-  time things with criterion.
-
-- Utils has been split up more.
-
-- Utils.Regex: regular expression compilation has been memoized, and
-  memoizing versions of regexReplace[CI] have been added, since
-  compiling regular expressions every time seems to be quite
-  expensive (#244).
- 
-- Utils.String: strWidth is now aware of multi-line strings (#242).
-
-- Read: parsers now use a consistent p suffix.
-
-- New dependencies: deepseq, uglymemo.
-
-- All the hledger packages' cabal files are now generated from
-  simpler, less redundant yaml files by hpack, in principle. In
-  practice, manual fixups are still needed until hpack gets better,
-  but it's still a win.
-
-0.26 (2015/7/12)
-
-- allow year parser to handle arbitrarily large years
-- Journal's Show instance reported one too many accounts
-- some cleanup of debug trace helpers
-- tighten up some date and account name parsers (don't accept leading spaces; hadddocks)
-- drop regexpr dependency
-
-0.25.1 (2015/4/29)
-
-- support/require base-compat >0.8 (#245)
-
-0.25 (2015/4/7)
-
-
-- GHC 7.10 compatibility (#239)
-
-0.24.1 (2015/3/15)
-
-- fix JournalReader "ctx" compilation warning
-- add some type signatures in Utils to help make ghci-web
-
-0.24 (2014/12/25)
-
-- fix combineJournalUpdates folding order
-- fix a regexReplaceCI bug
-- fix a splitAtElement bug with adjacent separators
-- mostly replace slow regexpr with regex-tdfa (fixes #189)
-- use the modern Text.Parsec API
-- allow transformers 0.4*
-- regexReplace now supports backreferences
-- Transactions now remember their parse location in the journal file
-- export Regexp types, disambiguate CsvReader's similarly-named type
-- export failIfInvalidMonth/Day (fixes #216)
-- track the commodity of zero amounts when possible
-  (useful eg for hledger-web's multi-commodity charts)
-- show posting dates in debug output
-- more debug helpers
-
-0.23.3 (2014/9/12)
-
-- allow transformers 0.4*
-
-0.23.2 (2014/5/8)
-
-- postingsReport: also fix date sorting of displayed postings (#184)
-
-0.23.1 (2014/5/7)
-
-- postingsReport: with disordered journal entries, postings before the
-  report start date could get wrongly included. (#184)
-
-0.23 (2014/5/1)
-
-- orDatesFrom -> spanDefaultsFrom
-
-0.22.2 (2014/4/16)
-
-- display years before 1000 with four digits, not three
-- avoid pretty-show to build with GHC < 7.4
-- allow text 1.1, drop data-pprint to build with GHC 7.8.x
-
-0.22.1 (2014/1/6) and older: see http://hledger.org/release-notes or doc/CHANGES.md.
diff --git a/CHANGES.md b/CHANGES.md
new file mode 100644
--- /dev/null
+++ b/CHANGES.md
@@ -0,0 +1,619 @@
+Internal/api/developer-ish changes in the hledger-lib (and hledger) packages.
+For user-visible changes, see the hledger package changelog.
+
+# 1.13 (2019/02/01)
+
+- in Journal's jtxns field, forecasted txns are appended rather than prepended
+
+- API changes:
+
+  added:
+  +setFullPrecision
+  +setMinimalPrecision
+  +expectParseStateOn
+  +embedFileRelative
+  +hereFileRelative
+
+  changed:
+  - amultiplier -> aismultiplier
+  - Amount fields reordered for clearer debug output
+  - tpreceding_comment_lines -> tprecedingcomment, reordered
+  - Hledger.Data.TransactionModifier.transactionModifierToFunction -> modifyTransactions
+  - Hledger.Read.Common.applyTransactionModifiers -> Hledger.Data.Journal.journalModifyTransactions
+
+  - HelpTemplate -> CommandDoc
+
+
+# 1.12 (2018/12/02)
+
+-   switch to megaparsec 7 (Alex Chen)
+    We now track the stack of include files in Journal ourselves, since
+    megaparsec dropped this feature.
+
+-   add 'ExceptT' layer to our parser monad again (Alex Chen)
+    We previously had a parser type, 'type ErroringJournalParser = ExceptT
+    String ...' for throwing parse errors without allowing further
+    backtracking. This parser type was removed under the assumption that it
+    would be possible to write our parser without this capability. However,
+    after a hairy backtracking bug, we would now prefer to have the option to
+    prevent backtracking.
+
+    -   Define a 'FinalParseError' type specifically for the 'ExceptT' layer
+    -   Any parse error can be raised as a "final" parse error
+    -   Tracks the stack of include files for parser errors, anticipating the
+        removal of the tracking of stacks of include files in megaparsec 7
+        -   Although a stack of include files is also tracked in the 'StateT
+            Journal' layer of the parser, it seems easier to guarantee correct
+            error messages in the 'ExceptT FinalParserError' layer
+        -   This does not make the 'StateT Journal' stack redundant because the
+            'ExceptT FinalParseError' stack cannot be used to detect cycles of
+            include files
+
+-   more support for location-aware parse errors when re-parsing (Alex Chen)
+
+-   make 'includedirectivep' an 'ErroringJournalParser' (Alex Chen)
+
+-   drop Ord instance breaking GHC 8.6 build (Peter Simons)
+
+-   flip the arguments of (divide\|multiply)\[Mixed\]Amount
+
+-   showTransaction: fix a case showing multiple missing amounts
+    showTransaction could sometimes hide the last posting's amount even if
+    one of the other posting amounts was already implcit, producing invalid
+    transaction output.
+
+-   plog, plogAt: add missing newline
+
+-   split up journalFinalise, reorder journal finalisation steps (#893) (Jesse Rosenthal)
+    The `journalFinalise` function has been split up, allowing more granular
+    control.
+
+-   journalSetTime --> journalSetLastReadTime
+
+-   journalSetFilePath has been removed, use journalAddFile instead
+
+# 1.11.1 (2018/10/06)
+
+-   add, lib: fix wrong transaction rendering in balance assertion errors
+    and when using the add command
+
+# 1.11 (2018/9/30)
+
+-   compilation now works when locale is unset (#849)
+
+-   all unit tests have been converted from HUnit+test-framework to easytest
+
+-   doctests now run quicker by default, by skipping reloading between tests.
+    This can be disabled by passing --slow to the doctests test suite
+    executable.
+
+-   doctests test suite executable now supports --verbose, which shows
+    progress output as tests are run if doctest 0.16.0+ is installed
+    (and hopefully is harmless otherwise).
+
+-   doctests now support file pattern arguments, provide more informative output.
+    Limiting to just the file(s) you're interested can make doctest start
+    much quicker. With one big caveat: you can limit the starting files,
+    but it always imports and tests all other local files those import.
+
+-   a bunch of custom Show instances have been replaced with defaults,
+    for easier troubleshooting. These were sometimes obscuring
+    important details, eg in test failure output. Our new policy is:
+    stick with default derived Show instances as far as possible, but
+    when necessary adjust them to valid haskell syntax so pretty-show
+    can pretty-print them (eg when they contain Day values, cf
+    https://github.com/haskell/time/issues/101). By convention, when
+    fields are shown in less than full detail, and/or in double-quoted
+    pseudo syntax, we show a double period (..) in the output.
+
+-   Amount has a new Show instance. Amount's show instance hid
+    important details by default, and showing more details required
+    increasing the debug level, which was inconvenient. Now it has a
+    single show instance which shows more information, is fairly
+    compact, and is pretty-printable.
+
+        ghci> usd 1
+        OLD:
+        Amount {acommodity="$", aquantity=1.00, ..}
+        NEW:
+        Amount {acommodity = "$", aquantity = 1.00, aprice = NoPrice, astyle = AmountStyle "L False 2 Just '.' Nothing..", amultiplier = False}
+
+    MixedAmount's show instance is unchanged, but showMixedAmountDebug
+    is affected by this change:
+
+        ghci> putStrLn $ showMixedAmountDebug $ Mixed [usd 1]
+        OLD:
+        Mixed [Amount {acommodity="$", aquantity=1.00, aprice=, astyle=AmountStyle {ascommodityside = L, ascommodityspaced = False, asprecision = 2, asdecimalpoint = Just '.', asdigitgroups = Nothing}}]
+        NEW:
+        Mixed [Amount {acommodity="$", aquantity=1.00, aprice=, astyle=AmountStyle "L False 2 Just '.' Nothing.."}]
+
+-   Same-line & next-line comments of transactions, postings, etc.
+    are now parsed a bit more precisely (followingcommentp).
+    Previously, parsing no comment gave the same result as an empty
+    comment (a single newline); now it gives an empty string.\
+    Also, and perhaps as a consequence of the above, when there's no
+    same-line comment but there is a next-line comment, we'll insert an
+    empty first line, since otherwise next-line comments would get moved
+    up to the same line when rendered.
+
+-   Hledger.Utils.Test exports HasCallStack
+
+-   queryDateSpan, queryDateSpan' now intersect date AND'ed date spans
+    instead of unioning them, and docs are clearer.
+
+-   pushAccount -> pushDeclaredAccount
+
+-   jaccounts -> jdeclaredaccounts
+
+-   AutoTransaction.hs -> PeriodicTransaction.hs & TransactionModifier.hs
+
+-   Hledger.Utils.Debug helpers have been renamed/cleaned up
+
+# 1.10 (2018/6/30)
+
+-   build cleanly with all supported GHC versions again (7.10 to 8.4)
+
+-   support/use latest base-compat (#794)
+
+-   support/require megaparsec 6.4+
+
+-   extensive refactoring and cleanup of parsers and related types and utilities
+
+-   readJournalFile(s) cleanup, these now use InputOpts
+
+-   doctests now run a bit faster (#802)
+
+# 1.9.1 (2018/4/30)
+
+-   new generic PeriodicReport, and some report-related type aliases
+
+-   new BudgetReport
+
+-   make (readJournal\|tryReader)s?WithOpts the default api, dropping "WithOpts"
+
+-   automated postings and command line account aliases happen earlier
+    in journal processing (see hledger changelog)
+
+# 1.9 (2018/3/31)
+
+-   support ghc 8.4, latest deps
+
+-   when the system text encoding is UTF-8, ignore any UTF-8 BOM prefix
+    found when reading files.
+
+-   CompoundBalanceReport amounts are now normally positive.
+    The bs/bse/cf/is commands now show normal income, liability and equity
+    balances as positive. Negative numbers now indicate a contra-balance
+    (eg an overdrawn checking account), a net loss, a negative net worth,
+    etc. This makes these reports more like conventional financial
+    statements, and easier to read and share with others. (experimental)
+
+-   splitSpan now returns no spans for an empty datespan
+
+-   don't count periodic/modifier txns in Journal debug output
+
+-   lib/ui/web/api: move embedded manual files to extra-source-files
+
+-   Use skipMany/skipSome for parsing spacenonewline (Moritz Kiefer)
+    This avoids allocating the list of space characters only to then
+    discard it.
+
+-   rename, clarify purpose of balanceReportFromMultiBalanceReport
+
+-   fix some hlint warnings
+
+-   add some easytest tests
+
+# 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)
+
+-   add readJournalFile\[s\]WithOpts, with simpler arguments and support
+    for detecting new transactions since the last read.
+
+-   query: add payee: and note: query terms, improve description/payee/note docs (Jakub Zárybnický, Simon Michael, #598, #608)
+
+-   journal, cli: make trailing whitespace significant in regex account aliases
+    Trailing whitespace in the replacement part of a regular expression
+    account alias is now significant. Eg, converting a parent account to
+    just an account name prefix: --alias '/:acct:/=:acct'
+
+-   timedot: allow a quantity of seconds, minutes, days, weeks, months
+    or years to be logged as Ns, Nm, Nd, Nw, Nmo, Ny
+
+-   csv: switch the order of generated postings, so account1 is first.
+    This simplifies things and facilitates future improvements.
+
+-   csv: show the "creating/using rules file" message only with --debug
+
+-   csv: fix multiple includes in one rules file
+
+-   csv: add "newest-first" rule for more robust same-day ordering
+
+-   deps: allow ansi-terminal 0.7
+
+-   deps: add missing parsec lower bound, possibly related to #596, fpco/stackage#2835
+
+-   deps: drop oldtime flag, require time 1.5+
+
+-   deps: remove ghc < 7.6 support, remove obsolete CPP conditionals
+
+-   deps: fix test suite with ghc 8.2
+
+# 1.3.1 (2017/8/25)
+
+-   Fix a bug with -H showing nothing for empty periods (#583, Nicholas Niro)
+    This patch fixes a bug that happened when using the -H option on
+    a period without any transaction. Previously, the behavior was no
+    output at all even though it should have shown the previous ending balances
+    of past transactions. (This is similar to previously using -H with -E,
+    but with the extra advantage of not showing empty accounts)
+
+-   allow megaparsec 6 (#594)
+
+-   allow megaparsec-6.1 (Hans-Peter Deifel)
+
+-   fix test suite with Cabal 2 (#596)
+
+# 1.3 (2017/6/30)
+
+journal: The "uncleared" transaction/posting status, and associated UI flags
+and keys, have been renamed to "unmarked" to remove ambiguity and
+confusion. This means that we have dropped the `--uncleared` flag,
+and our `-U` flag now matches only unmarked things and not pending
+ones. See the issue and linked mail list discussion for more
+background. (#564)
+
+csv: assigning to the "balance" field name creates balance
+assertions (#537, Dmitry Astapov).
+
+csv: Doubled minus signs are handled more robustly (fixes #524, Nicolas Wavrant, Simon Michael)
+
+Multiple "status:" query terms are now OR'd together. (#564)
+
+deps: allow megaparsec 5.3.
+
+# 1.2 (2017/3/31)
+
+## journal format
+
+A pipe character can optionally be used to delimit payee names in
+transaction descriptions, for more accurate querying and pivoting by
+payee. Eg, for a description like `payee name | additional notes`,
+the two parts will be accessible as pseudo-fields/tags named `payee`
+and `note`.
+
+Some journal parse errors now show the range of lines involved, not just the first.
+
+## ledger format
+
+The experimental `ledger:` reader based on the WIP ledger4 project has
+been disabled, reducing build dependencies.
+
+## Misc
+
+Fix a bug when tying the knot between postings and their parent transaction, reducing memory usage by about 10% (#483) (Mykola Orliuk)
+
+Fix a few spaceleaks (#413) (Moritz Kiefer)
+
+Add Ledger.Parse.Text to package.yaml, fixing a potential build failure.
+
+Allow megaparsec 5.2 (#503)
+
+Rename optserror -> usageError, consolidate with other error functions
+
+# 1.1 (2016/12/31)
+
+## journal format
+
+-   balance assignments are now supported (#438, #129, #157, #288)
+
+    This feature also brings a slight performance drop (\~5%);
+    optimisations welcome.
+
+-   also recognise `*.hledger` files as hledger journal format
+
+## ledger format
+
+-   use ledger-parse from the ledger4 project as an alternate reader for C++ Ledger journals
+
+    The idea is that some day we might get better compatibility with Ledger files this way.
+    Right now this reader is not very useful and will be used only if you explicitly select it with a `ledger:` prefix.
+    It parses transaction dates, descriptions, accounts and amounts, and ignores everything else.
+    Amount parsing is delegated to hledger's journal parser, and malformed amounts might be silently ignored.
+
+    This adds at least some of the following as new dependencies for hledger-lib:
+    parsers, parsec, attoparsec, trifecta.
+
+## misc
+
+-   update base lower bound to enforce GHC 7.10+
+
+    hledger-lib had a valid install plan with GHC 7.8, but currently requires GHC 7.10 to compile.
+    Now we require base 4.8+ everywhere to ensure the right GHC version at the start.
+
+-   Hledger.Read api cleanups
+
+-   rename dbgIO to dbg0IO, consistent with dbg0, and document a bug in dbg*IO
+
+-   make readJournalFiles \[f\] equivalent to readJournalFile f (#437)
+
+-   more general parser types enabling reuse outside of IO (#439)
+
+# 1.0.1 (2016/10/27)
+
+-   allow megaparsec 5.0 or 5.1
+
+# 1.0 (2016/10/26)
+
+## timedot format
+
+-   new "timedot" format for retroactive/approximate time logging.
+
+    Timedot is a plain text format for logging dated, categorised
+    quantities (eg time), 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.
+
+## timeclock format
+
+-   renamed "timelog" format to "timeclock", matching the emacs package
+
+-   sessions can no longer span file boundaries (unclocked-out
+
+    sessions will be auto-closed at the end of the file).
+
+-   transaction ids now count up rather than down (#394)
+
+-   timeclock files no longer support default year directives
+
+-   removed old code for appending timeclock transactions to journal transactions.
+
+    A holdover from the days when both were allowed in one file.
+
+## csv format
+
+-   fix empty field assignment parsing, rule parse errors after megaparsec port (#407) (Hans-Peter Deifel)
+
+## journal format
+
+-   journal files can now include timeclock or timedot files (#320)
+
+    (but not yet CSV files).
+
+-   fixed an issue with ordering of same-date transactions included from other files
+
+-   the "commodity" directive and "format" subdirective are now supported, allowing
+
+    full control of commodity style (#295) The commodity directive's
+    format subdirective can now be used to override the inferred
+    style for a commodity, eg to increase or decrease the
+    precision. This is at least a good workaround for #295.
+
+-   Ledger-style "apply account"/"end apply account" directives are now used to set a default parent account.
+
+-   the Ledger-style "account" directive is now accepted (and ignored).
+
+-   bracketed posting dates are more robust (#304)
+
+    Bracketed posting dates were fragile; they worked only if you
+    wrote full 10-character dates. Also some semantics were a bit
+    unclear. Now they should be robust, and have been documented
+    more clearly. This is a legacy undocumented Ledger syntax, but
+    it improves compatibility and might be preferable to the more
+    verbose "date:" tags if you write posting dates often (as I do).
+    Internally, bracketed posting dates are no longer considered to
+    be tags. Journal comment, tag, and posting date parsers have
+    been reworked, all with doctests.
+
+-   balance assertion failure messages are clearer
+
+-   with --debug=2, more detail about balance assertions is shown.
+
+## misc
+
+-   file parsers have been ported from Parsec to Megaparsec \o/ (#289, #366) (Alexey Shmalko, Moritz Kiefer)
+
+-   most hledger types have been converted from String to Text, reducing memory usage by 30%+ on large files
+
+-   file parsers have been simplified for easier troubleshooting (#275).
+
+    The journal/timeclock/timedot parsers, instead of constructing
+    opaque journal update functions which are later applied to build
+    the journal, now construct the journal directly by modifying the
+    parser state. This is easier to understand and debug. It also
+    rules out the possibility of journal updates being a space
+    leak. (They weren't, in fact this change increased memory usage
+    slightly, but that has been addressed in other ways). The
+    ParsedJournal type alias has been added to distinguish
+    "being-parsed" journals and "finalised" journals.
+
+-   file format detection is more robust.
+
+    The Journal, Timelog and Timedot readers' detectors now check
+    each line in the sample data, not just the first one. I think the
+    sample data is only about 30 chars right now, but even so this
+    fixed a format detection issue I was seeing.
+    Also, we now always try parsing stdin as journal format (not just sometimes).
+
+-   all file formats now produce transaction ids, not just journal (#394)
+
+-   git clone of the hledger repo on windows now works (#345)
+
+-   added missing benchmark file (#342)
+
+-   our stack.yaml files are more compatible across stack versions (#300)
+
+-   use newer file-embed to fix ghci working directory dependence (<https://github.com/snoyberg/file-embed/issues/18>)
+
+-   report more accurate dates in account transaction report when postings have their own dates
+
+    (affects hledger-ui and hledger-web registers).
+    The newly-named "transaction register date" is the date to be
+    displayed for that transaction in a transaction register, for
+    some current account and filter query. It is either the
+    transaction date from the journal ("transaction general date"),
+    or if postings to the current account and matched by the
+    register's filter query have their own dates, the earliest of
+    those posting dates.
+
+-   simplify account transactions report's running total.
+
+    The account transactions report used for hledger-ui and -web
+    registers now gives either the "period total" or "historical
+    total", depending strictly on the --historical flag. It doesn't
+    try to indicate whether the historical total is the accurate
+    historical balance (which depends on the user's report query).
+
+-   reloading a file now preserves the effect of options, query arguments etc.
+
+-   reloading a journal should now reload all included files as well.
+
+-   the Hledger.Read.* modules have been reorganised for better reuse.
+
+    Hledger.Read.Utils has been renamed Hledger.Read.Common
+    and holds low-level parsers & utilities; high-level read
+    utilities are now in Hledger.Read.
+
+-   clarify amount display style canonicalisation code and terminology a bit.
+
+    Individual amounts still have styles; from these we derive
+    the standard "commodity styles". In user docs, we might call
+    these "commodity formats" since they can be controlled by the
+    "format" subdirective in journal files.
+
+-   Journal is now a monoid
+
+-   expandPath now throws a proper IO error
+
+-   more unit tests, start using doctest
+
+0.27 (2015/10/30)
+
+-   The main hledger types now derive NFData, which makes it easier to
+    time things with criterion.
+
+-   Utils has been split up more.
+
+-   Utils.Regex: regular expression compilation has been memoized, and
+    memoizing versions of regexReplace\[CI\] have been added, since
+    compiling regular expressions every time seems to be quite
+    expensive (#244).
+
+-   Utils.String: strWidth is now aware of multi-line strings (#242).
+
+-   Read: parsers now use a consistent p suffix.
+
+-   New dependencies: deepseq, uglymemo.
+
+-   All the hledger packages' cabal files are now generated from
+    simpler, less redundant yaml files by hpack, in principle. In
+    practice, manual fixups are still needed until hpack gets better,
+    but it's still a win.
+
+0.26 (2015/7/12)
+
+-   allow year parser to handle arbitrarily large years
+-   Journal's Show instance reported one too many accounts
+-   some cleanup of debug trace helpers
+-   tighten up some date and account name parsers (don't accept leading spaces; hadddocks)
+-   drop regexpr dependency
+
+0.25.1 (2015/4/29)
+
+-   support/require base-compat >0.8 (#245)
+
+0.25 (2015/4/7)
+
+-   GHC 7.10 compatibility (#239)
+
+0.24.1 (2015/3/15)
+
+-   fix JournalReader "ctx" compilation warning
+-   add some type signatures in Utils to help make ghci-web
+
+0.24 (2014/12/25)
+
+-   fix combineJournalUpdates folding order
+-   fix a regexReplaceCI bug
+-   fix a splitAtElement bug with adjacent separators
+-   mostly replace slow regexpr with regex-tdfa (fixes #189)
+-   use the modern Text.Parsec API
+-   allow transformers 0.4*
+-   regexReplace now supports backreferences
+-   Transactions now remember their parse location in the journal file
+-   export Regexp types, disambiguate CsvReader's similarly-named type
+-   export failIfInvalidMonth/Day (fixes #216)
+-   track the commodity of zero amounts when possible
+    (useful eg for hledger-web's multi-commodity charts)
+-   show posting dates in debug output
+-   more debug helpers
+
+0.23.3 (2014/9/12)
+
+-   allow transformers 0.4*
+
+0.23.2 (2014/5/8)
+
+-   postingsReport: also fix date sorting of displayed postings (#184)
+
+0.23.1 (2014/5/7)
+
+-   postingsReport: with disordered journal entries, postings before the
+    report start date could get wrongly included. (#184)
+
+0.23 (2014/5/1)
+
+-   orDatesFrom -> spanDefaultsFrom
+
+0.22.2 (2014/4/16)
+
+-   display years before 1000 with four digits, not three
+-   avoid pretty-show to build with GHC < 7.4
+-   allow text 1.1, drop data-pprint to build with GHC 7.8.x
+
+0.22.1 (2014/1/6) and older: see http://hledger.org/release-notes or doc/CHANGES.md.
diff --git a/Hledger/Data/Account.hs b/Hledger/Data/Account.hs
--- a/Hledger/Data/Account.hs
+++ b/Hledger/Data/Account.hs
@@ -45,14 +45,14 @@
              -- ]
 
 nullacct = Account
-  { aname = ""
-  , adeclarationorder = Nothing
-  , aparent = Nothing
-  , asubs = []
-  , anumpostings = 0
-  , aebalance = nullmixedamt
-  , aibalance = nullmixedamt
-  , aboring = False
+  { aname            = ""
+  , adeclarationinfo = Nothing
+  , asubs            = []
+  , aparent          = Nothing
+  , aboring          = False
+  , anumpostings     = 0
+  , aebalance        = nullmixedamt
+  , aibalance        = nullmixedamt
   }
 
 -- | Derive 1. an account tree and 2. each account's total exclusive
@@ -83,7 +83,11 @@
 accountTree rootname as = nullacct{aname=rootname, asubs=map (uncurry accountTree') $ M.assocs m }
   where
     T m = treeFromPaths $ map expandAccountName as :: FastTree AccountName
-    accountTree' a (T m) = nullacct{aname=a, asubs=map (uncurry accountTree') $ M.assocs m}
+    accountTree' a (T m) =
+      nullacct{
+        aname=a
+       ,asubs=map (uncurry accountTree') $ M.assocs m
+       }
 
 -- | Tie the knot so all subaccounts' parents are set correctly.
 tieAccountParents :: Account -> Account
@@ -204,12 +208,11 @@
     maybeflip | normalsign==NormallyNegative = id
               | otherwise                  = flip
 
--- | Look up an account's declaration order, if any, from the Journal and set it.
--- This is the relative position of its account directive 
--- among the other account directives.
-accountSetDeclarationOrder :: Journal -> Account -> Account
-accountSetDeclarationOrder j a@Account{..} = 
-  a{adeclarationorder = findIndex (==aname) (jdeclaredaccounts j)}
+-- | Add extra info for this account derived from the Journal's
+-- account directives, if any (comment, tags, declaration order..).
+accountSetDeclarationInfo :: Journal -> Account -> Account
+accountSetDeclarationInfo j a@Account{..} =
+  a{ adeclarationinfo=lookup aname $ jdeclaredaccounts j }
 
 -- | Sort account names by the order in which they were declared in
 -- the journal, at each level of the account tree (ie within each
@@ -227,7 +230,7 @@
   drop 1 $                                            -- drop the root node that was added
   flattenAccounts $                                   -- convert to an account list
   sortAccountTreeByDeclaration $                      -- sort by declaration order (and name)
-  mapAccounts (accountSetDeclarationOrder j) $        -- add declaration order info  
+  mapAccounts (accountSetDeclarationInfo j) $         -- add declaration order info
   accountTree "root"                                  -- convert to an account tree
   as
 
@@ -243,9 +246,10 @@
       map sortAccountTreeByDeclaration $ asubs a
       }
 
+accountDeclarationOrderAndName :: Account -> (Int, AccountName)
 accountDeclarationOrderAndName a = (adeclarationorder', aname a)
   where
-    adeclarationorder' = fromMaybe maxBound (adeclarationorder a)
+    adeclarationorder' = maybe maxBound adideclarationorder $ adeclarationinfo a
 
 -- | Search an account list by name.
 lookupAccount :: AccountName -> [Account] -> Maybe Account
diff --git a/Hledger/Data/Amount.hs b/Hledger/Data/Amount.hs
--- a/Hledger/Data/Amount.hs
+++ b/Hledger/Data/Amount.hs
@@ -75,6 +75,8 @@
   maxprecisionwithpoint,
   setAmountPrecision,
   withPrecision,
+  setFullPrecision,
+  setMinimalPrecision,
   setAmountInternalPrecision,
   withInternalPrecision,
   setAmountDecimalPoint,
@@ -124,7 +126,7 @@
 ) where
 
 import Data.Char (isDigit)
-import Data.Decimal (roundTo)
+import Data.Decimal (roundTo, decimalPlaces, normalizeDecimal)
 import Data.Function (on)
 import Data.List
 import Data.Map (findWithDefault)
@@ -166,7 +168,7 @@
 
 -- | The empty simple amount.
 amount, nullamt :: Amount
-amount = Amount{acommodity="", aquantity=0, aprice=NoPrice, astyle=amountstyle, amultiplier=False}
+amount = Amount{acommodity="", aquantity=0, aprice=NoPrice, astyle=amountstyle, aismultiplier=False}
 nullamt = amount
 
 -- | A temporary value for parsed transactions which had no amount specified.
@@ -277,6 +279,23 @@
 -- | Set an amount's display precision, flipped.
 withPrecision :: Amount -> Int -> Amount
 withPrecision = flip setAmountPrecision
+
+-- | Increase an amount's display precision, if necessary, enough so
+-- that it will be shown exactly, with all significant decimal places
+-- (excluding trailing zeros).
+setFullPrecision :: Amount -> Amount
+setFullPrecision a = setAmountPrecision p a
+  where
+    p                = max displayprecision normalprecision
+    displayprecision = asprecision $ astyle a
+    normalprecision  = fromIntegral $ decimalPlaces $ normalizeDecimal $ aquantity a
+
+-- | Set an amount's display precision to just enough so that it will
+-- be shown exactly, with all significant decimal places.
+setMinimalPrecision :: Amount -> Amount
+setMinimalPrecision a = setAmountPrecision normalprecision a
+  where
+    normalprecision  = fromIntegral $ decimalPlaces $ normalizeDecimal $ aquantity a
 
 -- | Get a string representation of an amount for debugging,
 -- appropriate to the current debug level. 9 shows maximum detail.
diff --git a/Hledger/Data/Journal.hs b/Hledger/Data/Journal.hs
--- a/Hledger/Data/Journal.hs
+++ b/Hledger/Data/Journal.hs
@@ -1,5 +1,7 @@
 {-# LANGUAGE Rank2Types #-}
-{-# LANGUAGE StandaloneDeriving, OverloadedStrings #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE CPP #-}
 
 {-|
@@ -67,6 +69,7 @@
   journalCheckBalanceAssertions,
   journalNumberAndTieTransactions,
   journalUntieTransactions,
+  journalModifyTransactions,
   -- * Tests
   samplejournal,
   tests_Journal,
@@ -105,6 +108,7 @@
 import Hledger.Data.Amount
 import Hledger.Data.Dates
 import Hledger.Data.Transaction
+import Hledger.Data.TransactionModifier
 import Hledger.Data.Posting
 import Hledger.Query
 
@@ -262,7 +266,7 @@
 
 -- | Sorted unique account names declared by account directives in this journal.
 journalAccountNamesDeclared :: Journal -> [AccountName]
-journalAccountNamesDeclared = nub . sort . jdeclaredaccounts
+journalAccountNamesDeclared = nub . sort . map fst . jdeclaredaccounts
 
 -- | Sorted unique account names declared by account directives or posted to
 -- by transactions in this journal.
@@ -555,6 +559,11 @@
 journalUntieTransactions :: Transaction -> Transaction
 journalUntieTransactions t@Transaction{tpostings=ps} = t{tpostings=map (\p -> p{ptransaction=Nothing}) ps}
 
+-- | Apply any transaction modifier rules in the journal 
+-- (adding automated postings to transactions, eg).
+journalModifyTransactions :: Journal -> Journal
+journalModifyTransactions j = j{ jtxns = modifyTransactions (jtxnmodifiers j) (jtxns j) }
+
 -- | Check any balance assertions in the journal and return an error
 -- message if any of them fail.
 journalCheckBalanceAssertions :: Journal -> Either String Journal
@@ -569,54 +578,71 @@
 -- | Check a posting's balance assertion and return an error if it
 -- fails.
 checkBalanceAssertion :: Posting -> MixedAmount -> Either String ()
-checkBalanceAssertion p@Posting{ pbalanceassertion = Just ass } bal =
-  foldl' fold (Right ()) amts
-    where fold (Right _) cass = checkBalanceAssertionCommodity p cass bal
-          fold err _ = err
-          amt = baamount ass
-          amts = amt : if baexact ass
-            then map (\a -> a{ aquantity = 0 }) $ amounts $ filterMixedAmount (\a -> acommodity a /= assertedcomm) bal
-            else []
-          assertedcomm = acommodity amt
+checkBalanceAssertion p@Posting{pbalanceassertion=Just (BalanceAssertion{baamount,baexact})} actualbal =
+  foldl' f (Right ()) assertedamts
+    where
+      f (Right _) assertedamt = checkBalanceAssertionCommodity p assertedamt actualbal
+      f err _                 = err
+      assertedamts = baamount : otheramts
+        where
+          assertedcomm = acommodity baamount
+          otheramts | baexact   = map (\a -> a{ aquantity = 0 }) $ amounts $ filterMixedAmount (\a -> acommodity a /= assertedcomm) actualbal
+                    | otherwise = []
 checkBalanceAssertion _ _ = Right ()
 
+-- | Are the asserted balance and the actual balance
+-- exactly equal (disregarding display precision) ?
+-- The posting is used for creating an error message.
 checkBalanceAssertionCommodity :: Posting -> Amount -> MixedAmount -> Either String ()
-checkBalanceAssertionCommodity p amt bal
-  | isReallyZeroAmount diff = Right ()
-  | True    = Left err
-    where assertedcomm = acommodity amt
-          actualbal = fromMaybe nullamt $ find ((== assertedcomm) . acommodity) (amounts bal)
-          diff = amt - actualbal
-          diffplus | isNegativeAmount diff == False = "+"
-                   | otherwise = ""
-          err = printf (unlines
-                        [ "balance assertion error%s",
-                          "after posting:",
-                          "%s",
-                          "balance assertion details:",
-                          "date:       %s",
-                          "account:    %s",
-                          "commodity:  %s",
-                          "calculated: %s",
-                          "asserted:   %s (difference: %s)"
-                        ])
-            (case ptransaction p of
-               Nothing -> ":" -- shouldn't happen
-               Just t ->  printf " in %s:\nin transaction:\n%s"
-                          (showGenericSourcePos pos) (chomp $ showTransaction t) :: String
-                            where pos = baposition $ fromJust $ pbalanceassertion p)
-            (showPostingLine p)
-            (showDate $ postingDate p)
-            (T.unpack $ paccount p) -- XXX pack
-            assertedcomm
-            (showAmount actualbal)
-            (showAmount amt)
-            (diffplus ++ showAmount diff)
+checkBalanceAssertionCommodity p assertedamt actualbal
+  | pass      = Right ()
+  | otherwise = Left err
+    where
+      assertedcomm = acommodity assertedamt
+      actualbalincommodity = fromMaybe nullamt $ find ((== assertedcomm) . acommodity) (amounts actualbal)
+      pass =
+        aquantity
+        -- traceWith (("asserted:"++).showAmountDebug)
+        assertedamt ==
+        aquantity
+        -- traceWith (("actual:"++).showAmountDebug)
+        actualbalincommodity
+      diff = aquantity assertedamt - aquantity actualbalincommodity
+      err = printf (unlines
+                    [ "balance assertion: %s",
+                      "\nassertion details:",
+                      "date:       %s",
+                      "account:    %s",
+                      "commodity:  %s",
+                      -- "display precision:  %d",
+                      "calculated: %s", -- (at display precision: %s)",
+                      "asserted:   %s", -- (at display precision: %s)",
+                      "difference: %s"
+                    ])
+        (case ptransaction p of
+           Nothing -> "?" -- shouldn't happen
+           Just t ->  printf "%s\ntransaction:\n%s"
+                        (showGenericSourcePos pos)
+                        (chomp $ showTransaction t)
+                        :: String
+                        where
+                          pos = baposition $ fromJust $ pbalanceassertion p
+        )
+        (showDate $ postingDate p)
+        (T.unpack $ paccount p) -- XXX pack
+        assertedcomm
+        -- (asprecision $ astyle actualbalincommodity)  -- should be the standard display precision I think
+        (show $ aquantity actualbalincommodity)
+        -- (showAmount actualbalincommodity)
+        (show $ aquantity assertedamt)
+        -- (showAmount assertedamt)
+        (show diff)
 
 -- | Fill in any missing amounts and check that all journal transactions
--- balance, or return an error message. This is done after parsing all
--- amounts and applying canonical commodity styles, since balancing
--- depends on display precision. Reports only the first error encountered.
+-- balance and all balance assertions pass, or return an error message.
+-- This is done after parsing all amounts and applying canonical
+-- commodity styles, since balancing depends on display precision.
+-- Reports only the first error encountered.
 journalBalanceTransactions :: Bool -> Journal -> Either String Journal
 journalBalanceTransactions assrt j =
   runST $ journalBalanceTransactionsST 
@@ -627,6 +653,8 @@
     (fmap (\txns -> j{ jtxns = txns}) . getElems) -- summarise state
 
 -- | Helper used by 'journalBalanceTransactions' and 'journalCheckBalanceAssertions'.
+-- Balances transactions, applies balance assignments, and checks balance assertions
+-- at the same time.
 journalBalanceTransactionsST ::
   Bool
   -> Journal
@@ -1063,7 +1091,7 @@
                  ["assets:bank:checking" `post` usd 1
                  ,"income:salary" `post` missingamt
                  ],
-             tpreceding_comment_lines=""
+             tprecedingcomment=""
            }
           ,
            txnTieKnot $ Transaction {
@@ -1080,7 +1108,7 @@
                  ["assets:bank:checking" `post` usd 1
                  ,"income:gifts" `post` missingamt
                  ],
-             tpreceding_comment_lines=""
+             tprecedingcomment=""
            }
           ,
            txnTieKnot $ Transaction {
@@ -1097,7 +1125,7 @@
                  ["assets:bank:saving" `post` usd 1
                  ,"assets:bank:checking" `post` usd (-1)
                  ],
-             tpreceding_comment_lines=""
+             tprecedingcomment=""
            }
           ,
            txnTieKnot $ Transaction {
@@ -1114,7 +1142,7 @@
                        ,"expenses:supplies" `post` usd 1
                        ,"assets:cash" `post` missingamt
                        ],
-             tpreceding_comment_lines=""
+             tprecedingcomment=""
            }
           ,
            txnTieKnot $ Transaction {
@@ -1130,7 +1158,7 @@
              tpostings=["assets:bank:checking" `post` usd 1
                        ,"liabilities:debts" `post` usd (-1)
                        ],
-             tpreceding_comment_lines=""
+             tprecedingcomment=""
            }
           ,
            txnTieKnot $ Transaction {
@@ -1146,7 +1174,7 @@
              tpostings=["liabilities:debts" `post` usd 1
                        ,"assets:bank:checking" `post` usd (-1)
                        ],
-             tpreceding_comment_lines=""
+             tprecedingcomment=""
            }
           ]
          }
diff --git a/Hledger/Data/Timeclock.hs b/Hledger/Data/Timeclock.hs
--- a/Hledger/Data/Timeclock.hs
+++ b/Hledger/Data/Timeclock.hs
@@ -95,7 +95,7 @@
             tcomment     = "",
             ttags        = [],
             tpostings    = ps,
-            tpreceding_comment_lines=""
+            tprecedingcomment=""
           }
       itime    = tldatetime i
       otime    = tldatetime o
diff --git a/Hledger/Data/Transaction.hs b/Hledger/Data/Transaction.hs
--- a/Hledger/Data/Transaction.hs
+++ b/Hledger/Data/Transaction.hs
@@ -35,7 +35,7 @@
   showTransaction,
   showTransactionUnelided,
   showTransactionUnelidedOneLineAmounts,
-  showPostingLine,
+  -- showPostingLine,
   showPostingLines,
   -- * GenericSourcePos
   sourceFilePath,
@@ -90,7 +90,7 @@
                     tcomment="",
                     ttags=[],
                     tpostings=[],
-                    tpreceding_comment_lines=""
+                    tprecedingcomment=""
                   }
 
 {-|
@@ -246,14 +246,17 @@
       case renderCommentLines (pcomment p) of []   -> ("",[])
                                               c:cs -> (c,cs)
 
--- | Show a posting's status, account name and amount on one line. 
--- Used in balance assertion errors.
-showPostingLine p =
-  indent $
-  if pstatus p == Cleared then "* " else "" ++
-  showAccountName Nothing (ptype p) (paccount p) ++
-  "    " ++
-  showMixedAmountOneLine (pamount p)
+-- | Render a posting, simply. Used in balance assertion errors.
+-- showPostingLine p =
+--   indent $
+--   if pstatus p == Cleared then "* " else "" ++  -- XXX show !
+--   showAccountName Nothing (ptype p) (paccount p) ++
+--   "    " ++
+--   showMixedAmountOneLine (pamount p) ++
+--   assertion
+--   where
+--     -- XXX extract, handle ==
+--     assertion = maybe "" ((" = " ++) . showAmountWithZeroCommodity . baamount) $ pbalanceassertion p
 
 -- | Render a posting, at the appropriate width for aligning with
 -- its siblings if any. Used by the rewrite command. 
@@ -689,10 +692,10 @@
 
   ,tests "showTransaction" [
      test "show a balanced transaction, eliding last amount" $
-       let t = Transaction 0 nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "coopportunity" "" []
+       let t = Transaction 0 "" nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "coopportunity" "" []
                 [posting{paccount="expenses:food:groceries", pamount=Mixed [usd 47.18], ptransaction=Just t}
                 ,posting{paccount="assets:checking", pamount=Mixed [usd (-47.18)], ptransaction=Just t}
-                ] ""
+                ]
        in 
         showTransaction t
          `is`
@@ -704,10 +707,10 @@
           ]
 
     ,test "show a balanced transaction, no eliding" $
-       (let t = Transaction 0 nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "coopportunity" "" []
+       (let t = Transaction 0 "" nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "coopportunity" "" []
                 [posting{paccount="expenses:food:groceries", pamount=Mixed [usd 47.18], ptransaction=Just t}
                 ,posting{paccount="assets:checking", pamount=Mixed [usd (-47.18)], ptransaction=Just t}
-                ] ""
+                ]
         in showTransactionUnelided t)
        `is`
        (unlines
@@ -720,10 +723,10 @@
      -- document some cases that arise in debug/testing:
     ,test "show an unbalanced transaction, should not elide" $
        (showTransaction
-        (txnTieKnot $ Transaction 0 nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "coopportunity" "" []
+        (txnTieKnot $ Transaction 0 "" nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "coopportunity" "" []
          [posting{paccount="expenses:food:groceries", pamount=Mixed [usd 47.18]}
          ,posting{paccount="assets:checking", pamount=Mixed [usd (-47.19)]}
-         ] ""))
+         ]))
        `is`
        (unlines
         ["2007/01/28 coopportunity"
@@ -734,9 +737,9 @@
 
     ,test "show an unbalanced transaction with one posting, should not elide" $
        (showTransaction
-        (txnTieKnot $ Transaction 0 nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "coopportunity" "" []
+        (txnTieKnot $ Transaction 0 "" nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "coopportunity" "" []
          [posting{paccount="expenses:food:groceries", pamount=Mixed [usd 47.18]}
-         ] ""))
+         ]))
        `is`
        (unlines
         ["2007/01/28 coopportunity"
@@ -746,9 +749,9 @@
 
     ,test "show a transaction with one posting and a missing amount" $
        (showTransaction
-        (txnTieKnot $ Transaction 0 nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "coopportunity" "" []
+        (txnTieKnot $ Transaction 0 "" nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "coopportunity" "" []
          [posting{paccount="expenses:food:groceries", pamount=missingmixedamt}
-         ] ""))
+         ]))
        `is`
        (unlines
         ["2007/01/28 coopportunity"
@@ -758,10 +761,10 @@
 
     ,test "show a transaction with a priced commodityless amount" $
        (showTransaction
-        (txnTieKnot $ Transaction 0 nullsourcepos (parsedate "2010/01/01") Nothing Unmarked "" "x" "" []
+        (txnTieKnot $ Transaction 0 "" nullsourcepos (parsedate "2010/01/01") Nothing Unmarked "" "x" "" []
          [posting{paccount="a", pamount=Mixed [num 1 `at` (usd 2 `withPrecision` 0)]}
          ,posting{paccount="b", pamount= missingmixedamt}
-         ] ""))
+         ]))
        `is`
        (unlines
         ["2010/01/01 x"
@@ -774,95 +777,95 @@
   ,tests "balanceTransaction" [
      test "detect unbalanced entry, sign error" $
                     (expectLeft $ balanceTransaction Nothing
-                           (Transaction 0 nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "test" "" []
+                           (Transaction 0 "" nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "test" "" []
                             [posting{paccount="a", pamount=Mixed [usd 1]}
                             ,posting{paccount="b", pamount=Mixed [usd 1]}
-                            ] ""))
+                            ]))
 
     ,test "detect unbalanced entry, multiple missing amounts" $
                     (expectLeft $ balanceTransaction Nothing
-                           (Transaction 0 nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "test" "" []
+                           (Transaction 0 "" nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "test" "" []
                             [posting{paccount="a", pamount=missingmixedamt}
                             ,posting{paccount="b", pamount=missingmixedamt}
-                            ] ""))
+                            ]))
 
     ,test "one missing amount is inferred" $
          (pamount . last . tpostings <$> balanceTransaction
            Nothing
-           (Transaction 0 nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "" "" []
+           (Transaction 0 "" nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "" "" []
              [posting{paccount="a", pamount=Mixed [usd 1]}
              ,posting{paccount="b", pamount=missingmixedamt}
-             ] ""))
+             ]))
          `is` Right (Mixed [usd (-1)])
 
     ,test "conversion price is inferred" $
          (pamount . head . tpostings <$> balanceTransaction
            Nothing
-           (Transaction 0 nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "" "" []
+           (Transaction 0 "" nullsourcepos (parsedate "2007/01/28") Nothing Unmarked "" "" "" []
              [posting{paccount="a", pamount=Mixed [usd 1.35]}
              ,posting{paccount="b", pamount=Mixed [eur (-1)]}
-             ] ""))
+             ]))
          `is` Right (Mixed [usd 1.35 @@ (eur 1 `withPrecision` maxprecision)])
 
     ,test "balanceTransaction balances based on cost if there are unit prices" $
        expectRight $
-       balanceTransaction Nothing (Transaction 0 nullsourcepos (parsedate "2011/01/01") Nothing Unmarked "" "" "" []
+       balanceTransaction Nothing (Transaction 0 "" nullsourcepos (parsedate "2011/01/01") Nothing Unmarked "" "" "" []
                            [posting{paccount="a", pamount=Mixed [usd 1 `at` eur 2]}
                            ,posting{paccount="a", pamount=Mixed [usd (-2) `at` eur 1]}
-                           ] "")
+                           ])
 
     ,test "balanceTransaction balances based on cost if there are total prices" $
        expectRight $
-       balanceTransaction Nothing (Transaction 0 nullsourcepos (parsedate "2011/01/01") Nothing Unmarked "" "" "" []
+       balanceTransaction Nothing (Transaction 0 "" nullsourcepos (parsedate "2011/01/01") Nothing Unmarked "" "" "" []
                            [posting{paccount="a", pamount=Mixed [usd 1    @@ eur 1]}
                            ,posting{paccount="a", pamount=Mixed [usd (-2) @@ eur 1]}
-                           ] "")
+                           ])
   ]
 
   ,tests "isTransactionBalanced" [
      test "detect balanced" $ expect $
-       isTransactionBalanced Nothing $ Transaction 0 nullsourcepos (parsedate "2009/01/01") Nothing Unmarked "" "a" "" []
+       isTransactionBalanced Nothing $ Transaction 0 "" nullsourcepos (parsedate "2009/01/01") Nothing Unmarked "" "a" "" []
              [posting{paccount="b", pamount=Mixed [usd 1.00]}
              ,posting{paccount="c", pamount=Mixed [usd (-1.00)]}
-             ] ""
+             ]
      
     ,test "detect unbalanced" $ expect $
-       not $ isTransactionBalanced Nothing $ Transaction 0 nullsourcepos (parsedate "2009/01/01") Nothing Unmarked "" "a" "" []
+       not $ isTransactionBalanced Nothing $ Transaction 0 "" nullsourcepos (parsedate "2009/01/01") Nothing Unmarked "" "a" "" []
              [posting{paccount="b", pamount=Mixed [usd 1.00]}
              ,posting{paccount="c", pamount=Mixed [usd (-1.01)]}
-             ] ""
+             ]
      
     ,test "detect unbalanced, one posting" $ expect $
-       not $ isTransactionBalanced Nothing $ Transaction 0 nullsourcepos (parsedate "2009/01/01") Nothing Unmarked "" "a" "" []
+       not $ isTransactionBalanced Nothing $ Transaction 0 "" nullsourcepos (parsedate "2009/01/01") Nothing Unmarked "" "a" "" []
              [posting{paccount="b", pamount=Mixed [usd 1.00]}
-             ] ""
+             ]
      
     ,test "one zero posting is considered balanced for now" $ expect $
-       isTransactionBalanced Nothing $ Transaction 0 nullsourcepos (parsedate "2009/01/01") Nothing Unmarked "" "a" "" []
+       isTransactionBalanced Nothing $ Transaction 0 "" nullsourcepos (parsedate "2009/01/01") Nothing Unmarked "" "a" "" []
              [posting{paccount="b", pamount=Mixed [usd 0]}
-             ] ""
+             ]
      
     ,test "virtual postings don't need to balance" $ expect $
-       isTransactionBalanced Nothing $ Transaction 0 nullsourcepos (parsedate "2009/01/01") Nothing Unmarked "" "a" "" []
+       isTransactionBalanced Nothing $ Transaction 0 "" nullsourcepos (parsedate "2009/01/01") Nothing Unmarked "" "a" "" []
              [posting{paccount="b", pamount=Mixed [usd 1.00]}
              ,posting{paccount="c", pamount=Mixed [usd (-1.00)]}
              ,posting{paccount="d", pamount=Mixed [usd 100], ptype=VirtualPosting}
-             ] ""
+             ]
      
     ,test "balanced virtual postings need to balance among themselves" $ expect $
-       not $ isTransactionBalanced Nothing $ Transaction 0 nullsourcepos (parsedate "2009/01/01") Nothing Unmarked "" "a" "" []
+       not $ isTransactionBalanced Nothing $ Transaction 0 "" nullsourcepos (parsedate "2009/01/01") Nothing Unmarked "" "a" "" []
              [posting{paccount="b", pamount=Mixed [usd 1.00]}
              ,posting{paccount="c", pamount=Mixed [usd (-1.00)]}
              ,posting{paccount="d", pamount=Mixed [usd 100], ptype=BalancedVirtualPosting}
-             ] ""
+             ]
      
     ,test "balanced virtual postings need to balance among themselves (2)" $ expect $
-       isTransactionBalanced Nothing $ Transaction 0 nullsourcepos (parsedate "2009/01/01") Nothing Unmarked "" "a" "" []
+       isTransactionBalanced Nothing $ Transaction 0 "" nullsourcepos (parsedate "2009/01/01") Nothing Unmarked "" "a" "" []
              [posting{paccount="b", pamount=Mixed [usd 1.00]}
              ,posting{paccount="c", pamount=Mixed [usd (-1.00)]}
              ,posting{paccount="d", pamount=Mixed [usd 100], ptype=BalancedVirtualPosting}
              ,posting{paccount="3", pamount=Mixed [usd (-100)], ptype=BalancedVirtualPosting}
-             ] ""
+             ]
      
   ]
 
diff --git a/Hledger/Data/TransactionModifier.hs b/Hledger/Data/TransactionModifier.hs
--- a/Hledger/Data/TransactionModifier.hs
+++ b/Hledger/Data/TransactionModifier.hs
@@ -8,7 +8,7 @@
 
 -}
 module Hledger.Data.TransactionModifier (
-    transactionModifierToFunction
+   modifyTransactions
 )
 where
 
@@ -32,6 +32,12 @@
 -- >>> import Hledger.Data.Transaction
 -- >>> import Hledger.Data.Journal
 
+-- | Apply all the given transaction modifiers, in turn, to each transaction.
+modifyTransactions :: [TransactionModifier] -> [Transaction] -> [Transaction]
+modifyTransactions tmods ts = map applymods ts
+  where
+    applymods = foldr (flip (.) . transactionModifierToFunction) id tmods
+
 -- | Converts a 'TransactionModifier' to a 'Transaction'-transforming function,
 -- which applies the modification(s) specified by the TransactionModifier.
 -- Currently this means adding automated postings when certain other postings are present.
@@ -47,7 +53,7 @@
 -- 0000/01/01
 --     ping           $1.00
 -- <BLANKLINE>
--- >>> putStr $ showTransaction $ transactionModifierToFunction (TransactionModifier "ping" ["pong" `post` amount{amultiplier=True, aquantity=3}]) nulltransaction{tpostings=["ping" `post` usd 2]}
+-- >>> putStr $ showTransaction $ transactionModifierToFunction (TransactionModifier "ping" ["pong" `post` amount{aismultiplier=True, aquantity=3}]) nulltransaction{tpostings=["ping" `post` usd 2]}
 -- 0000/01/01
 --     ping           $2.00
 --     pong           $6.00
@@ -111,7 +117,7 @@
 postingRuleMultiplier :: TMPostingRule -> Maybe Quantity
 postingRuleMultiplier p =
     case amounts $ pamount p of
-        [a] | amultiplier a -> Just $ aquantity a
+        [a] | aismultiplier a -> Just $ aquantity a
         _                   -> Nothing
 
 renderPostingCommentDates :: Posting -> Posting
diff --git a/Hledger/Data/Types.hs b/Hledger/Data/Types.hs
--- a/Hledger/Data/Types.hs
+++ b/Hledger/Data/Types.hs
@@ -201,12 +201,12 @@
 instance NFData Commodity
 
 data Amount = Amount {
-      acommodity  :: CommoditySymbol,
-      aquantity   :: Quantity,
-      aprice      :: Price,           -- ^ the (fixed) price for this amount, if any
+      acommodity  :: CommoditySymbol,   -- commodity symbol, or special value "AUTO"
+      aquantity   :: Quantity,          -- numeric quantity, or zero in case of "AUTO"
+      aismultiplier :: Bool,            -- ^ kludge: a flag marking this amount and posting as a multiplier
+                                        --   in a TMPostingRule. In a regular Posting, should always be false.
       astyle      :: AmountStyle,
-      amultiplier :: Bool             -- ^ kludge: a flag marking this amount and posting as a multiplier
-                                      --   in a TMPostingRule. In a regular Posting, should always be false.
+      aprice      :: Price            -- ^ the (fixed, transaction-specific) price for this amount, if any
     } deriving (Eq,Ord,Typeable,Data,Generic,Show)
 
 instance NFData Amount
@@ -302,8 +302,9 @@
 --    prevents the constraint ‘(Data p0)’ from being solved.
 --    Probable fix: use a type annotation to specify what ‘p0’ should be.
 data Transaction = Transaction {
-      tindex                   :: Integer,   -- ^ this transaction's 1-based position in the input stream, or 0 when not available
-      tsourcepos               :: GenericSourcePos,
+      tindex                   :: Integer,   -- ^ this transaction's 1-based position in the transaction stream, or 0 when not available
+      tprecedingcomment        :: Text,      -- ^ any comment lines immediately preceding this transaction
+      tsourcepos               :: GenericSourcePos,  -- ^ the file position where the date starts
       tdate                    :: Day,
       tdate2                   :: Maybe Day,
       tstatus                  :: Status,
@@ -311,8 +312,7 @@
       tdescription             :: Text,
       tcomment                 :: Text,      -- ^ this transaction's comment lines, as a single non-indented multi-line string
       ttags                    :: [Tag],     -- ^ tag names and values, extracted from the comment
-      tpostings                :: [Posting], -- ^ this transaction's postings
-      tpreceding_comment_lines :: Text       -- ^ any comment lines immediately preceding this transaction
+      tpostings                :: [Posting]  -- ^ this transaction's postings
     } deriving (Eq,Typeable,Data,Generic,Show)
 
 instance NFData Transaction
@@ -336,7 +336,7 @@
 
 -- | A transaction modifier transformation, which adds an extra posting
 -- to the matched posting's transaction.
--- Can be like a regular posting, or the amount can have the amultiplier flag set,
+-- Can be like a regular posting, or the amount can have the aismultiplier flag set,
 -- indicating that it's a multiplier for the matched posting's amount.
 type TMPostingRule = Posting
 
@@ -410,7 +410,7 @@
   ,jparsetimeclockentries :: [TimeclockEntry]                       -- ^ timeclock sessions which have not been clocked out
   ,jincludefilestack      :: [FilePath]
   -- principal data
-  ,jdeclaredaccounts      :: [AccountName]                          -- ^ Accounts declared by account directives, in parse order (after journal finalisation) 
+  ,jdeclaredaccounts      :: [(AccountName,AccountDeclarationInfo)] -- ^ Accounts declared by account directives, in parse order (after journal finalisation) 
   ,jdeclaredaccounttypes  :: M.Map AccountType [AccountName]        -- ^ Accounts whose type has been declared in account directives (usually 5 top-level accounts) 
   ,jcommodities           :: M.Map CommoditySymbol Commodity        -- ^ commodities and formats declared by commodity directives
   ,jinferredcommodities   :: M.Map CommoditySymbol AmountStyle      -- ^ commodities and formats inferred from journal amounts  TODO misnamed - jusedstyles
@@ -439,18 +439,36 @@
 -- The --output-format option selects one of these for output.
 type StorageFormat = String
 
--- | An account, with name, balances and links to parent/subaccounts
--- which let you walk up or down the account tree.
+-- | Extra information about an account that can be derived from
+-- its account directive (and the other account directives).
+data AccountDeclarationInfo = AccountDeclarationInfo {
+   adicomment          :: Text   -- ^ any comment lines following an account directive for this account
+  ,aditags             :: [Tag]  -- ^ tags extracted from the account comment, if any
+  ,adideclarationorder :: Int    -- ^ the order in which this account was declared,
+                                 --   relative to other account declarations, during parsing (1..)
+} deriving (Eq,Show,Data,Generic)
+
+instance NFData AccountDeclarationInfo
+
+nullaccountdeclarationinfo = AccountDeclarationInfo {
+   adicomment          = ""
+  ,aditags             = []
+  ,adideclarationorder = 0
+}
+
+-- | An account, with its balances, parent/subaccount relationships, etc.
+-- Only the name is required; the other fields are added when needed.
 data Account = Account {
-  aname                     :: AccountName,   -- ^ this account's full name
-  adeclarationorder         :: Maybe Int  ,   -- ^ the relative position of this account's account directive, if any. Normally a natural number. 
-  aebalance                 :: MixedAmount,   -- ^ this account's balance, excluding subaccounts
-  asubs                     :: [Account],     -- ^ sub-accounts
-  anumpostings              :: Int,           -- ^ number of postings to this account
-  -- derived from the above :
-  aibalance                 :: MixedAmount,   -- ^ this account's balance, including subaccounts
-  aparent                   :: Maybe Account, -- ^ parent account
-  aboring                   :: Bool           -- ^ used in the accounts report to label elidable parents
+   aname                     :: AccountName    -- ^ this account's full name
+  ,adeclarationinfo          :: Maybe AccountDeclarationInfo  -- ^ optional extra info from account directives
+  -- relationships in the tree
+  ,asubs                     :: [Account]      -- ^ this account's sub-accounts
+  ,aparent                   :: Maybe Account  -- ^ parent account
+  ,aboring                   :: Bool           -- ^ used in the accounts report to label elidable parents
+  -- balance information
+  ,anumpostings              :: Int            -- ^ the number of postings to this account
+  ,aebalance                 :: MixedAmount    -- ^ this account's balance, excluding subaccounts
+  ,aibalance                 :: MixedAmount    -- ^ this account's balance, including subaccounts
   } deriving (Typeable, Data, Generic)
 
 -- | Whether an account's balance is normally a positive number (in 
diff --git a/Hledger/Read.hs b/Hledger/Read.hs
--- a/Hledger/Read.hs
+++ b/Hledger/Read.hs
@@ -171,7 +171,7 @@
 -- directives & aliases do not affect subsequent sibling or parent files.
 -- They do affect included child files though. 
 -- Also the final parse state saved in the Journal does span all files.
-readJournalFiles :: InputOpts -> [FilePath] -> IO (Either String Journal)
+readJournalFiles :: InputOpts -> [PrefixedFilePath] -> IO (Either String Journal)
 readJournalFiles iopts =
   (right mconcat1 . sequence <$>) . mapM (readJournalFile iopts)
   where
diff --git a/Hledger/Read/Common.hs b/Hledger/Read/Common.hs
--- a/Hledger/Read/Common.hs
+++ b/Hledger/Read/Common.hs
@@ -33,7 +33,6 @@
   rejp,
   genericSourcePos,
   journalSourcePos,
-  applyTransactionModifiers,
   parseAndFinaliseJournal,
   parseAndFinaliseJournal',
   setYear,
@@ -42,7 +41,6 @@
   getDefaultCommodityAndStyle,
   getDefaultAmountStyle,
   getAmountStyle,
-  pushDeclaredAccount,
   addDeclaredAccountType,
   pushParentAccount,
   popParentAccount,
@@ -229,14 +227,6 @@
             | otherwise = unPos $ sourceLine p' -- might be at end of file withat last new-line
 
 
--- | Apply any transaction modifier rules in the journal 
--- (adding automated postings to transactions, eg).
-applyTransactionModifiers :: Journal -> Journal
-applyTransactionModifiers j = j { jtxns = map applyallmodifiers $ jtxns j }
-  where
-    applyallmodifiers = 
-      foldr (flip (.) . transactionModifierToFunction) id (jtxnmodifiers j)
-
 -- | Given a megaparsec ParsedJournal parser, input options, file
 -- path and file content: parse and post-process a Journal, or give an error.
 parseAndFinaliseJournal :: ErroringJournalParser IO ParsedJournal -> InputOpts
@@ -264,14 +254,24 @@
         -- time. If we are only running once, we reorder and follow
         -- the options for checking assertions.
         let fj = if auto_ iopts && (not . null . jtxnmodifiers) pj
-                 then applyTransactionModifiers <$>
-                      (journalBalanceTransactions False $
-                       journalReverse $
-                       journalApplyCommodityStyles pj) >>=
-                      (\j -> journalBalanceTransactions (not $ ignore_assertions_ iopts) $
-                             journalAddFile (f, txt) $
-                             journalSetLastReadTime t $
-                             j)
+
+                 -- transaction modifiers are active
+                 then
+                   -- first pass, doing most of the work
+                     (
+                      (journalModifyTransactions <$>) $  -- add auto postings after balancing ? #893b fails
+                      journalBalanceTransactions False $
+                      -- journalModifyTransactions <$>   -- add auto postings before balancing ? probably #893a, #928, #938 fail
+                      journalReverse $
+                      journalAddFile (f, txt) $
+                      journalApplyCommodityStyles pj)
+                   -- second pass, checking balance assertions
+                   >>= (\j ->
+                      journalBalanceTransactions (not $ ignore_assertions_ iopts) $
+                      journalSetLastReadTime t $
+                      j)
+
+                 -- transaction modifiers are not active
                  else journalBalanceTransactions (not $ ignore_assertions_ iopts) $
                       journalReverse $
                       journalAddFile (f, txt) $
@@ -283,6 +283,8 @@
             Right j -> return j
             Left e  -> throwError e
 
+-- Like parseAndFinaliseJournal but takes a (non-Erroring) JournalParser.
+-- Used for timeclock/timedot. XXX let them use parseAndFinaliseJournal instead
 parseAndFinaliseJournal' :: JournalParser IO ParsedJournal -> InputOpts
                            -> FilePath -> Text -> ExceptT String IO Journal
 parseAndFinaliseJournal' parser iopts f txt = do
@@ -303,7 +305,7 @@
       -- time. If we are only running once, we reorder and follow the
       -- options for checking assertions.
       let fj = if auto_ iopts && (not . null . jtxnmodifiers) pj
-               then applyTransactionModifiers <$>
+               then journalModifyTransactions <$>
                     (journalBalanceTransactions False $
                      journalReverse $
                      journalApplyCommodityStyles pj) >>=
@@ -352,9 +354,6 @@
     let effectiveStyle = listToMaybe $ catMaybes [specificStyle, defaultStyle]
     return effectiveStyle
 
-pushDeclaredAccount :: AccountName -> JournalParser m ()
-pushDeclaredAccount acct = modify' (\j -> j{jdeclaredaccounts = acct : jdeclaredaccounts j})
-
 addDeclaredAccountType :: AccountName -> AccountType -> JournalParser m ()
 addDeclaredAccountType acct atype = 
   modify' (\j -> j{jdeclaredaccounttypes = M.insertWith (++) atype [acct] (jdeclaredaccounttypes j)})
@@ -630,7 +629,7 @@
     let numRegion = (offBeforeNum, offAfterNum)
     (q,prec,mdec,mgrps) <- lift $ interpretNumber numRegion suggestedStyle ambiguousRawNum mExponent
     let s = amountstyle{ascommodityside=L, ascommodityspaced=commodityspaced, asprecision=prec, asdecimalpoint=mdec, asdigitgroups=mgrps}
-    return $ Amount c (sign (sign2 q)) NoPrice s mult
+    return $ nullamt{acommodity=c, aquantity=sign (sign2 q), aismultiplier=mult, astyle=s, aprice=NoPrice}
 
   rightornosymbolamountp :: Bool -> (Decimal -> Decimal) -> JournalParser m Amount
   rightornosymbolamountp mult sign = label "amount" $ do
@@ -646,7 +645,7 @@
         suggestedStyle <- getAmountStyle c
         (q,prec,mdec,mgrps) <- lift $ interpretNumber numRegion suggestedStyle ambiguousRawNum mExponent
         let s = amountstyle{ascommodityside=R, ascommodityspaced=commodityspaced, asprecision=prec, asdecimalpoint=mdec, asdigitgroups=mgrps}
-        return $ Amount c (sign q) NoPrice s mult
+        return $ nullamt{acommodity=c, aquantity=sign q, aismultiplier=mult, astyle=s, aprice=NoPrice}
       -- no symbol amount
       Nothing -> do
         suggestedStyle <- getDefaultAmountStyle
@@ -657,7 +656,7 @@
         let (c,s) = case (mult, defcs) of
               (False, Just (defc,defs)) -> (defc, defs{asprecision=max (asprecision defs) prec})
               _ -> ("", amountstyle{asprecision=prec, asdecimalpoint=mdec, asdigitgroups=mgrps})
-        return $ Amount c (sign q) NoPrice s mult
+        return $ nullamt{acommodity=c, aquantity=sign q, aismultiplier=mult, astyle=s, aprice=NoPrice}
 
   -- For reducing code duplication. Doesn't parse anything. Has the type
   -- of a parser only in order to throw parse errors (for convenience).
@@ -721,7 +720,7 @@
   priceConstructor <- char '@' *> pure TotalPrice <|> pure UnitPrice
 
   lift (skipMany spacenonewline)
-  priceAmount <- amountwithoutpricep <?> "amount (as a price)"
+  priceAmount <- amountwithoutpricep <?> "unpriced amount (specifying a price)"
 
   pure $ priceConstructor priceAmount
 
@@ -731,14 +730,19 @@
   char '='
   exact <- optional $ try $ char '='
   lift (skipMany spacenonewline)
-  a <- amountp <?> "amount (for a balance assertion or assignment)" -- XXX should restrict to a simple amount
+  -- this amount can have a price; balance assertions ignore it,
+  -- but balance assignments will use it
+  a <- amountp <?> "amount (for a balance assertion or assignment)"
   return BalanceAssertion
     { baamount = a
     , baexact = isJust exact
     , baposition = sourcepos
     }
 
--- http://ledger-cli.org/3.0/doc/ledger3.html#Fixing-Lot-Prices
+-- Parse a Ledger-style fixed lot price: {=PRICE}
+-- https://www.ledger-cli.org/3.0/doc/ledger3.html#Fixing-Lot-Prices .
+-- Currently we ignore these (hledger's @ PRICE is equivalent),
+-- and we don't parse a Ledger-style {PRICE} (equivalent to Ledger's @ PRICE).
 fixedlotpricep :: JournalParser m (Maybe Amount)
 fixedlotpricep = optional $ do
   try $ do
@@ -747,7 +751,7 @@
   lift (skipMany spacenonewline)
   char '='
   lift (skipMany spacenonewline)
-  a <- amountp -- XXX should restrict to a simple amount
+  a <- amountwithoutpricep <?> "unpriced amount (for an ignored ledger-style fixed lot price)"
   lift (skipMany spacenonewline)
   char '}'
   return a
@@ -1297,7 +1301,7 @@
 
 tests_Common = tests "Common" [
 
-  tests "amountp" [
+   tests "amountp" [
     test "basic"                  $ expectParseEq amountp "$47.18"     (usd 47.18)
    ,test "ends with decimal mark" $ expectParseEq amountp "$1."        (usd 1  `withPrecision` 0)
    ,test "unit price"             $ expectParseEq amountp "$10 @ €0.5" 
diff --git a/Hledger/Read/CsvReader.hs b/Hledger/Read/CsvReader.hs
--- a/Hledger/Read/CsvReader.hs
+++ b/Hledger/Read/CsvReader.hs
@@ -746,7 +746,7 @@
       tcode                    = T.pack code,
       tdescription             = T.pack description,
       tcomment                 = T.pack comment,
-      tpreceding_comment_lines = T.pack precomment,
+      tprecedingcomment = T.pack precomment,
       tpostings                =
         [posting {paccount=account1, pamount=amount1, ptransaction=Just t, pbalanceassertion=toAssertion <$> balance}
         ,posting {paccount=account2, pamount=amount2, ptransaction=Just t}
diff --git a/Hledger/Read/JournalReader.hs b/Hledger/Read/JournalReader.hs
--- a/Hledger/Read/JournalReader.hs
+++ b/Hledger/Read/JournalReader.hs
@@ -66,9 +66,8 @@
 import "base-compat-batteries" Prelude.Compat hiding (readFile)
 import qualified Control.Exception as C
 import Control.Monad
-import Control.Monad.Except (ExceptT(..))
+import Control.Monad.Except (ExceptT(..), runExceptT)
 import Control.Monad.State.Strict
-import Data.Maybe
 import qualified Data.Map.Strict as M
 import Data.Text (Text)
 import Data.String
@@ -253,36 +252,81 @@
     Right res -> pure res
     Left errMsg -> fail errMsg
 
+-- Parse an account directive, adding its info to the journal's
+-- list of account declarations.
 accountdirectivep :: JournalParser m ()
 accountdirectivep = do
+  off <- getOffset -- XXX figure out a more precise position later
+
   string "account"
   lift (skipSome spacenonewline)
+
   -- the account name, possibly modified by preceding alias or apply account directives
   acct <- modifiedaccountnamep
-  -- and maybe something else after two or more spaces ?
-  matype :: Maybe AccountType <- lift $ fmap (fromMaybe Nothing) $ optional $ try $ do
+
+  -- maybe an account type code (ALERX) after two or more spaces
+  -- XXX added in 1.11, deprecated in 1.13, remove in 1.14
+  mtypecode :: Maybe Char <- lift $ optional $ try $ do
     skipSome spacenonewline -- at least one more space in addition to the one consumed by modifiedaccountp 
-    choice [
-      -- a numeric account code, as supported in 1.9-1.10 ? currently ignored
-       some digitChar >> return Nothing
-      -- a letter account type code (ALERX), as added in 1.11 ?
-      ,char 'A' >> return (Just Asset) 
-      ,char 'L' >> return (Just Liability) 
-      ,char 'E' >> return (Just Equity) 
-      ,char 'R' >> return (Just Revenue) 
-      ,char 'X' >> return (Just Expense) 
-      ]
-  -- and maybe a comment on this and/or following lines ? (ignore for now)
-  (_cmt, _tags) <- lift transactioncommentp
-  -- and maybe Ledger-style subdirectives ? (ignore)
+    choice $ map char "ALERX"
+
+  -- maybe a comment, on this and/or following lines
+  (cmt, tags) <- lift transactioncommentp
+  
+  -- maybe Ledger-style subdirectives (ignored)
   skipMany indentedlinep
 
+  -- an account type may have been set by account type code or a tag;
+  -- the latter takes precedence
+  let
+    mtypecode' :: Maybe Text = maybe
+      (T.singleton <$> mtypecode)
+      Just
+      $ lookup accountTypeTagName tags
+    metype = parseAccountTypeCode <$> mtypecode'
+
   -- update the journal
-  case matype of
-    Nothing    -> return ()
-    Just atype -> addDeclaredAccountType acct atype
-  pushDeclaredAccount acct
+  addAccountDeclaration (acct, cmt, tags)
+  case metype of
+    Nothing         -> return ()
+    Just (Right t)  -> addDeclaredAccountType acct t
+    Just (Left err) -> customFailure $ parseErrorAt off err
 
+-- The special tag used for declaring account type. XXX change to "class" ?
+accountTypeTagName = "type"
+
+parseAccountTypeCode :: Text -> Either String AccountType
+parseAccountTypeCode s =
+  case T.toLower s of
+    "asset"     -> Right Asset
+    "a"         -> Right Asset
+    "liability" -> Right Liability
+    "l"         -> Right Liability
+    "equity"    -> Right Equity
+    "e"         -> Right Equity
+    "revenue"   -> Right Revenue
+    "r"         -> Right Revenue
+    "expense"   -> Right Expense
+    "x"         -> Right Expense
+    _           -> Left err
+  where
+    err = "invalid account type code "++T.unpack s++", should be one of " ++
+          (intercalate ", " $ ["A","L","E","R","X","ASSET","LIABILITY","EQUITY","REVENUE","EXPENSE"])
+
+-- Add an account declaration to the journal, auto-numbering it.
+addAccountDeclaration :: (AccountName,Text,[Tag]) -> JournalParser m ()
+addAccountDeclaration (a,cmt,tags) =
+  modify' (\j ->
+             let
+               decls = jdeclaredaccounts j
+               d     = (a, nullaccountdeclarationinfo{
+                              adicomment          = cmt
+                             ,aditags             = tags
+                             ,adideclarationorder = length decls + 1
+                             })
+             in
+               j{jdeclaredaccounts = d:decls})
+
 indentedlinep :: JournalParser m String
 indentedlinep = lift (skipSome spacenonewline) >> (rstrip <$> lift restofline)
 
@@ -525,23 +569,18 @@
       customFailure $ parseErrorAtRegion offset1 offset2 $
            "remainder of period expression cannot be parsed"
         <> "\nperhaps you need to terminate the period expression with a double space?"
+        <> "\na double space is required between period expression and description/comment"
     pure pexp
 
   -- In periodic transactions, the period expression has an additional constraint:
   case checkPeriodicTransactionStartDate interval span periodtxt of
     Just e -> customFailure $ parseErrorAt off e
     Nothing -> pure ()
-  -- The line can end here, or it can continue with one or more spaces
-  -- and then zero or more of the following fields. A bit awkward.
-  (status, code, description, (comment, tags)) <- lift $
-    (<|>) (eolof >> return (Unmarked, "", "", ("", []))) $ do
-      skipSome spacenonewline
-      s         <- statusp
-      c         <- codep
-      desc      <- T.strip <$> descriptionp
-      (cmt, ts) <- transactioncommentp
-      return (s,c,desc,(cmt,ts))
-
+  
+  status <- lift statusp <?> "cleared status"
+  code <- lift codep <?> "transaction code"
+  description <- lift $ T.strip <$> descriptionp
+  (comment, tags) <- lift transactioncommentp
   -- next lines; use same year determined above
   postings <- postingsp (Just $ first3 $ toGregorian refdate)
 
@@ -573,7 +612,7 @@
   postings <- postingsp (Just year)
   endpos <- getSourcePos
   let sourcepos = journalSourcePos startpos endpos
-  return $ txnTieKnot $ Transaction 0 sourcepos date edate status code description comment tags postings ""
+  return $ txnTieKnot $ Transaction 0 "" sourcepos date edate status code description comment tags postings
 
 --- ** postings
 
@@ -693,6 +732,19 @@
         ,ptcomment     = ""
         }
 
+    ,test "Just date, no description" $ expectParseEq periodictransactionp
+      "~ 2019-01-04\n"
+      nullperiodictransaction {
+         ptperiodexpr  = "2019-01-04"
+        ,ptinterval    = NoInterval
+        ,ptspan        = DateSpan (Just $ fromGregorian 2019 1 4) (Just $ fromGregorian 2019 1 5)
+        ,ptdescription = ""
+        ,ptcomment     = ""
+        }
+
+    ,test "Just date, no description + empty transaction comment" $ expectParse periodictransactionp
+      "~ 2019-01-04\n  ;\n  a  1\n  b\n"
+
     ]
 
   ,tests "postingp" [
@@ -760,7 +812,7 @@
         ])
       nulltransaction{
         tsourcepos=JournalSourcePos "" (1,7),  -- XXX why 7 here ?
-        tpreceding_comment_lines="",
+        tprecedingcomment="",
         tdate=fromGregorian 2012 5 14,
         tdate2=Just $ fromGregorian 2012 5 15,
         tstatus=Unmarked,
@@ -800,7 +852,16 @@
         ,"  b"
         ," "
         ]
-  
+
+    ,test "transactionp parses an empty transaction comment following whitespace line" $
+      expect $ isRight $ rjp transactionp $ T.unlines
+        ["2012/1/1"
+        ,"  ;"
+        ,"  a  1"
+        ,"  b"
+        ," "
+        ]
+
     ,test "comments everywhere, two postings parsed" $
       expectParseEqOn transactionp 
         (T.unlines
@@ -824,11 +885,16 @@
     ]
 
   ,test "accountdirectivep" $ do
-    test "with-comment" $ expectParse accountdirectivep "account a:b  ; a comment\n"
+    test "with-comment"       $ expectParse accountdirectivep "account a:b  ; a comment\n"
     test "does-not-support-!" $ expectParseError accountdirectivep "!account a:b\n" ""
-    test "account-sort-code" $ expectParse accountdirectivep "account a:b  1000\n"
-    test "account-type-code" $ expectParse accountdirectivep "account a:b  A\n"
-    test "account-type-tag" $ expectParse accountdirectivep "account a:b  ; type:asset\n"
+    test "account-type-code"  $ expectParse accountdirectivep "account a:b  A\n"
+    test "account-type-tag"   $ expectParseStateOn accountdirectivep "account a:b  ; type:asset\n"
+      jdeclaredaccounts
+      [("a:b", AccountDeclarationInfo{adicomment          = "type:asset\n"
+                                     ,aditags             = [("type","asset")]
+                                     ,adideclarationorder = 1
+                                     })
+      ]
 
   ,test "commodityconversiondirectivep" $ do
      expectParse commodityconversiondirectivep "C 1h = $50.00\n"
@@ -868,5 +934,13 @@
   ,tests "journalp" [
     test "empty file" $ expectParseEqE journalp "" nulljournal
     ]
+
+   -- these are defined here rather than in Common so they can use journalp
+  ,tests "parseAndFinaliseJournal" [
+    test "basic" $ do
+        ej <- io $ runExceptT $ parseAndFinaliseJournal journalp definputopts "" "2019-1-1\n"
+        let Right j = ej
+        expectEqPP [""] $ journalFilePaths j
+   ]
 
   ]
diff --git a/Hledger/Reports/BalanceReport.hs b/Hledger/Reports/BalanceReport.hs
--- a/Hledger/Reports/BalanceReport.hs
+++ b/Hledger/Reports/BalanceReport.hs
@@ -198,7 +198,7 @@
             [posting {paccount="assets:bank:checking", pamount=Mixed [usd 1]}
             ,posting {paccount="income:salary", pamount=missingmixedamt}
             ],
-          tpreceding_comment_lines=""
+          tprecedingcomment=""
         }
       ]
     }
diff --git a/Hledger/Reports/BudgetReport.hs b/Hledger/Reports/BudgetReport.hs
--- a/Hledger/Reports/BudgetReport.hs
+++ b/Hledger/Reports/BudgetReport.hs
@@ -64,12 +64,18 @@
 -- actual balance changes from the regular transactions,
 -- and compare these to get a 'BudgetReport'.
 -- Unbudgeted accounts may be hidden or renamed (see budgetRollup).
-budgetReport :: ReportOpts -> Bool -> Bool -> DateSpan -> Day -> Journal -> BudgetReport
-budgetReport ropts assrt showunbudgeted reportspan d j =
+budgetReport :: ReportOpts -> Bool -> DateSpan -> Day -> Journal -> BudgetReport
+budgetReport ropts' assrt reportspan d j =
   let
+    -- Budget report demands ALTree mode to ensure subaccounts and subaccount budgets are properly handled
+    -- and that reports with and without --empty make sense when compared side by side
+    ropts = ropts' { accountlistmode_ = ALTree }
+    showunbudgeted = empty_ ropts
     q = queryFromOpts d ropts 
     budgetedaccts = 
       dbg2 "budgetedacctsinperiod" $
+      nub $ 
+      concatMap expandAccountName $
       accountNamesFromPostings $ 
       concatMap tpostings $ 
       concatMap (flip runPeriodicTransaction reportspan) $ 
@@ -77,7 +83,7 @@
     actualj = dbg1 "actualj" $ budgetRollUp budgetedaccts showunbudgeted j
     budgetj = dbg1 "budgetj" $ budgetJournal assrt ropts reportspan j
     actualreport@(MultiBalanceReport (actualspans, _, _)) = dbg1 "actualreport" $ multiBalanceReport ropts  q actualj
-    budgetgoalreport@(MultiBalanceReport (_, budgetgoalitems, budgetgoaltotals)) = dbg1 "budgetgoalreport" $ multiBalanceReport ropts q budgetj
+    budgetgoalreport@(MultiBalanceReport (_, budgetgoalitems, budgetgoaltotals)) = dbg1 "budgetgoalreport" $ multiBalanceReport (ropts{empty_=True}) q budgetj
     budgetgoalreport'
       -- If no interval is specified:
       -- budgetgoalreport's span might be shorter actualreport's due to periodic txns; 
@@ -157,7 +163,7 @@
 --
 -- 2. subaccounts with no budget goal are merged with their closest parent account
 --    with a budget goal, so that only budgeted accounts are shown. 
---    This can be disabled by --show-unbudgeted.
+--    This can be disabled by --empty.
 --
 budgetRollUp :: [AccountName] -> Bool -> Journal -> Journal
 budgetRollUp budgetedaccts showunbudgeted j = j { jtxns = remapTxn <$> jtxns j }
@@ -262,18 +268,24 @@
 
 -- | Render a budget report as plain text suitable for console output.
 budgetReportAsText :: ReportOpts -> BudgetReport -> String
-budgetReportAsText ropts budgetr =
+budgetReportAsText ropts budgetr@(PeriodicReport ( _, rows, _)) =
   printf "Budget performance in %s:\n\n" (showDateSpan $ budgetReportSpan budgetr)
   ++ 
-  tableAsText ropts showcell (budgetReportAsTable ropts budgetr)
+  tableAsText ropts showcell (maybetranspose $ budgetReportAsTable ropts budgetr)
   where
+    actualwidth =
+      maximum [ maybe 0 (length . showMixedAmountOneLineWithoutPrice) amt
+      | (_, _, _, amtandgoals, _, _) <- rows
+      , (amt, _) <- amtandgoals ]
+    budgetwidth =
+      maximum [ maybe 0 (length . showMixedAmountOneLineWithoutPrice) goal
+      | (_, _, _, amtandgoals, _, _) <- rows
+      , (_, goal) <- amtandgoals ]
     -- XXX lay out actual, percentage and/or goal in the single table cell for now, should probably use separate cells
     showcell :: (Maybe Change, Maybe BudgetGoal) -> String
     showcell (mactual, mbudget) = actualstr ++ " " ++ budgetstr
       where
-        actualwidth  = 7
         percentwidth = 4
-        budgetwidth  = 5
         actual = fromMaybe 0 mactual
         actualstr = printf ("%"++show actualwidth++"s") (showamt actual)
         budgetstr = case mbudget of
@@ -307,6 +319,9 @@
 
     -- don't show the budget amount in color, it messes up alignment
     showbudgetamt = showMixedAmountOneLineWithoutPrice
+
+    maybetranspose | transpose_ ropts = \(Table rh ch vals) -> Table ch rh (transpose vals)
+                   | otherwise       = id
 
 -- | Build a 'Table' from a multi-column balance report.
 budgetReportAsTable :: ReportOpts -> BudgetReport -> Table String String (Maybe MixedAmount, Maybe MixedAmount)
diff --git a/Hledger/Reports/MultiBalanceReports.hs b/Hledger/Reports/MultiBalanceReports.hs
--- a/Hledger/Reports/MultiBalanceReports.hs
+++ b/Hledger/Reports/MultiBalanceReports.hs
@@ -314,7 +314,7 @@
       (map showw aitems) `is` (map showw eitems)
       ((\(_, b, _) -> showMixedAmountDebug b) atotal) `is` (showMixedAmountDebug etotal) -- we only check the sum of the totals
     usd0 = usd 0
-    amount0 = Amount {acommodity="$", aquantity=0, aprice=NoPrice, astyle=AmountStyle {ascommodityside = L, ascommodityspaced = False, asprecision = 2, asdecimalpoint = Just '.', asdigitgroups = Nothing}, amultiplier=False}
+    amount0 = Amount {acommodity="$", aquantity=0, aprice=NoPrice, astyle=AmountStyle {ascommodityside = L, ascommodityspaced = False, asprecision = 2, asdecimalpoint = Just '.', asdigitgroups = Nothing}, aismultiplier=False}
   in 
    tests "multiBalanceReport" [
       test "null journal"  $
diff --git a/Hledger/Reports/ReportOptions.hs b/Hledger/Reports/ReportOptions.hs
--- a/Hledger/Reports/ReportOptions.hs
+++ b/Hledger/Reports/ReportOptions.hs
@@ -112,6 +112,7 @@
       --   normally positive for a more conventional display.   
     ,color_          :: Bool
     ,forecast_       :: Bool
+    ,transpose_      :: Bool
  } deriving (Show, Data, Typeable)
 
 instance Default ReportOpts where def = defreportopts
@@ -144,6 +145,7 @@
     def
     def
     def
+    def
 
 rawOptsToReportOpts :: RawOpts -> IO ReportOpts
 rawOptsToReportOpts rawopts = checkReportOpts <$> do
@@ -176,6 +178,7 @@
     ,pretty_tables_ = boolopt "pretty-tables" rawopts'
     ,color_       = color
     ,forecast_    = boolopt "forecast" rawopts'
+    ,transpose_   = boolopt "transpose" rawopts'
     }
 
 -- | Do extra validation of raw option values, raising an error if there's a problem.
diff --git a/Hledger/Utils.hs b/Hledger/Utils.hs
--- a/Hledger/Utils.hs
+++ b/Hledger/Utils.hs
@@ -37,15 +37,19 @@
 import Control.Monad (liftM, when)
 -- import Data.Char
 import Data.Default
+import Data.FileEmbed (makeRelativeToProject, embedFile)
 import Data.List
 -- import Data.Maybe
 -- import Data.PPrint
+import Data.String.Here (hereFile)
 import Data.Text (Text)
 import qualified Data.Text.IO as T
 import Data.Time.Clock
 import Data.Time.LocalTime
 -- import Data.Text (Text)
 -- import qualified Data.Text as T
+import Language.Haskell.TH.Quote (QuasiQuoter(..))
+import Language.Haskell.TH.Syntax (Q, Exp)
 import System.Directory (getHomeDirectory)
 import System.FilePath((</>), isRelative)
 import System.IO
@@ -220,6 +224,18 @@
 mapM' :: Monad f => (a -> f b) -> [a] -> f [b]
 mapM' f = sequence' . map f
 
+-- | Like embedFile, but takes a path relative to the package directory.
+-- Similar to hereFileRelative ?
+embedFileRelative :: FilePath -> Q Exp
+embedFileRelative f = makeRelativeToProject f >>= embedFile
+
+-- | Like hereFile, but takes a path relative to the package directory.
+-- Similar to embedFileRelative ?
+hereFileRelative :: FilePath -> Q Exp
+hereFileRelative f = makeRelativeToProject f >>= hereFileExp
+  where
+    QuasiQuoter{quoteExp=hereFileExp} = hereFile
+    
 tests_Utils = tests "Utils" [
   tests_Text
   ]
diff --git a/Hledger/Utils/Test.hs b/Hledger/Utils/Test.hs
--- a/Hledger/Utils/Test.hs
+++ b/Hledger/Utils/Test.hs
@@ -23,12 +23,13 @@
   ,expectParseEqE
   ,expectParseEqOn
   ,expectParseEqOnE
+  ,expectParseStateOn
 ) 
 where
 
 import Control.Exception
 import Control.Monad.Except (ExceptT, runExceptT)
-import Control.Monad.State.Strict (StateT, evalStateT)
+import Control.Monad.State.Strict (StateT, evalStateT, execStateT)
 #if !(MIN_VERSION_base(4,11,0))
 import Data.Monoid ((<>))
 #endif
@@ -106,7 +107,6 @@
 
 -- | Test that this stateful parser runnable in IO successfully parses 
 -- all of the given input text, showing the parse error if it fails. 
-
 -- Suitable for hledger's JournalParser parsers.
 expectParse :: (Monoid st, Eq a, Show a, HasCallStack) => 
   StateT st (ParsecT CustomErr T.Text IO) a -> T.Text -> E.Test ()
@@ -216,3 +216,17 @@
              (expectEqPP expected . f)
              ep
 
+-- | Run a stateful parser in IO like expectParse, then compare the
+-- final state (the wrapped state, not megaparsec's internal state),
+-- transformed by the given function, with the given expected value.
+expectParseStateOn :: (HasCallStack, Monoid st, Eq b, Show b) =>
+     StateT st (ParsecT CustomErr T.Text IO) a
+  -> T.Text
+  -> (st -> b)
+  -> b
+  -> E.Test ()
+expectParseStateOn parser input f expected = do
+  es <- E.io $ runParserT (execStateT (parser <* eof) mempty) "" input
+  case es of
+    Left err -> fail $ (++"\n") $ ("\nparse error at "++) $ customErrorBundlePretty err
+    Right s  -> expectEqPP expected $ f s
diff --git a/hledger-lib.cabal b/hledger-lib.cabal
--- a/hledger-lib.cabal
+++ b/hledger-lib.cabal
@@ -1,13 +1,13 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.31.0.
+-- This file has been generated from package.yaml by hpack version 0.31.1.
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 8e0ce73c7c86c909a78d4d06e8566f8b66bc1df89f508da0b05df073c4ecd7c9
+-- hash: c17b44c345a89a13650ca3efcba7d7e8311e9312acfd08dff5f2716e70ca29d7
 
 name:           hledger-lib
-version:        1.12
+version:        1.13
 synopsis:       Core data types, parsers and functionality for the hledger accounting tools
 description:    This is a reusable library containing hledger's core functionality.
                 .
@@ -28,7 +28,7 @@
 tested-with:    GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.3
 build-type:     Simple
 extra-source-files:
-    CHANGES
+    CHANGES.md
     README
     hledger_csv.5
     hledger_csv.txt
@@ -121,8 +121,10 @@
     , directory
     , easytest
     , extra
+    , file-embed >=0.0.10
     , filepath
     , hashtables >=1.2.3.1
+    , here
     , megaparsec >=7.0.0 && <8
     , mtl
     , mtl-compat
@@ -134,6 +136,7 @@
     , safe >=0.2
     , split >=0.1
     , tabular >=0.2
+    , template-haskell
     , text >=1.2
     , time >=1.5
     , transformers >=0.2
@@ -221,8 +224,10 @@
     , doctest >=0.16
     , easytest
     , extra
+    , file-embed >=0.0.10
     , filepath
     , hashtables >=1.2.3.1
+    , here
     , megaparsec >=7.0.0 && <8
     , mtl
     , mtl-compat
@@ -234,6 +239,7 @@
     , safe >=0.2
     , split >=0.1
     , tabular >=0.2
+    , template-haskell
     , text >=1.2
     , time >=1.5
     , transformers >=0.2
@@ -320,8 +326,10 @@
     , directory
     , easytest
     , extra
+    , file-embed >=0.0.10
     , filepath
     , hashtables >=1.2.3.1
+    , here
     , hledger-lib
     , megaparsec >=7.0.0 && <8
     , mtl
@@ -334,6 +342,7 @@
     , safe >=0.2
     , split >=0.1
     , tabular >=0.2
+    , template-haskell
     , text >=1.2
     , time >=1.5
     , transformers >=0.2
diff --git a/hledger_csv.5 b/hledger_csv.5
--- a/hledger_csv.5
+++ b/hledger_csv.5
@@ -1,5 +1,5 @@
 
-.TH "hledger_csv" "5" "December 2018" "hledger 1.12" "hledger User Manuals"
+.TH "hledger_csv" "5" "February 2019" "hledger 1.13" "hledger User Manuals"
 
 
 
@@ -29,7 +29,7 @@
 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.
+some example rules, which you\[aq]ll need to adjust.
 .PP
 At minimum, the rules file must identify the \f[C]date\f[] and
 \f[C]amount\f[] fields.
@@ -90,7 +90,7 @@
 \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.
+You\[aq]ll need this whenever your CSV data contains header lines.
 Eg:
 .IP
 .nf
@@ -104,23 +104,23 @@
 \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.
+\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
+#\ for\ dates\ like\ "11/06/2013":
+date\-format\ %m/%d/%Y
 \f[]
 .fi
 .IP
 .nf
 \f[C]
-#\ for\ dates\ like\ "11/06/2013":
-date\-format\ %m/%d/%Y
+#\ for\ dates\ like\ "6/11/2013"\ (note\ the\ \-\ to\ make\ leading\ zeros\ optional):
+date\-format\ %\-d/%\-m/%Y
 \f[]
 .fi
 .IP
@@ -140,7 +140,7 @@
 .SS field list
 .PP
 \f[C]fields\f[]\f[I]\f[CI]FIELDNAME1\f[I]\f[],
-\f[I]\f[CI]FIELDNAME2\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
@@ -192,7 +192,7 @@
 .PD 0
 .P
 .PD
-\ \ \ \ \f[I]\f[CI]FIELDASSIGNMENTS\f[I]\f[]\&...
+\ \ \ \ \f[I]\f[CI]FIELDASSIGNMENTS\f[I]\f[]...
 .PP
 \f[C]if\f[]
 .PD 0
@@ -202,16 +202,16 @@
 .PD 0
 .P
 .PD
-\f[I]\f[CI]PATTERN\f[I]\f[]\&...
+\f[I]\f[CI]PATTERN\f[I]\f[]...
 .PD 0
 .P
 .PD
-\ \ \ \ \f[I]\f[CI]FIELDASSIGNMENTS\f[I]\f[]\&...
+\ \ \ \ \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
+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.
@@ -244,7 +244,7 @@
 .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.
+the current file\[aq]s directory.
 Eg:
 .IP
 .nf
@@ -261,9 +261,9 @@
 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.
+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
@@ -274,8 +274,9 @@
 .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
+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
diff --git a/hledger_csv.info b/hledger_csv.info
--- a/hledger_csv.info
+++ b/hledger_csv.info
@@ -3,7 +3,7 @@
 
 File: hledger_csv.info,  Node: Top,  Next: CSV RULES,  Up: (dir)
 
-hledger_csv(5) hledger 1.12
+hledger_csv(5) hledger 1.13
 ***************************
 
 hledger can read CSV (comma-separated value) files as if they were
@@ -113,12 +113,12 @@
 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 "6/11/2013" (note the - to make leading zeros optional):
+date-format %-d/%-m/%Y
+
 # for dates like "2013-Nov-06":
 date-format %Y-%h-%d
 
@@ -323,27 +323,27 @@
 Ref: #skip2627
 Node: date-format2799
 Ref: #date-format2926
-Node: field list3432
-Ref: #field-list3569
-Node: field assignment4274
-Ref: #field-assignment4429
-Node: conditional block4933
-Ref: #conditional-block5087
-Node: include5983
-Ref: #include6113
-Node: newest-first6344
-Ref: #newest-first6458
-Node: CSV TIPS6869
-Ref: #csv-tips6963
-Node: CSV ordering7081
-Ref: #csv-ordering7199
-Node: CSV accounts7380
-Ref: #csv-accounts7518
-Node: CSV amounts7772
-Ref: #csv-amounts7918
-Node: CSV balance assertions8693
-Ref: #csv-balance-assertions8875
-Node: Reading multiple CSV files9080
-Ref: #reading-multiple-csv-files9250
+Node: field list3476
+Ref: #field-list3613
+Node: field assignment4318
+Ref: #field-assignment4473
+Node: conditional block4977
+Ref: #conditional-block5131
+Node: include6027
+Ref: #include6157
+Node: newest-first6388
+Ref: #newest-first6502
+Node: CSV TIPS6913
+Ref: #csv-tips7007
+Node: CSV ordering7125
+Ref: #csv-ordering7243
+Node: CSV accounts7424
+Ref: #csv-accounts7562
+Node: CSV amounts7816
+Ref: #csv-amounts7962
+Node: CSV balance assertions8737
+Ref: #csv-balance-assertions8919
+Node: Reading multiple CSV files9124
+Ref: #reading-multiple-csv-files9294
 
 End Tag Table
diff --git a/hledger_csv.txt b/hledger_csv.txt
--- a/hledger_csv.txt
+++ b/hledger_csv.txt
@@ -88,12 +88,12 @@
        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 "6/11/2013" (note the - to make leading zeros optional):
+              date-format %-d/%-m/%Y
+
               # for dates like "2013-Nov-06":
               date-format %Y-%h-%d
 
@@ -249,4 +249,4 @@
 
 
 
-hledger 1.12                     December 2018                  hledger_csv(5)
+hledger 1.13                     February 2019                  hledger_csv(5)
diff --git a/hledger_journal.5 b/hledger_journal.5
--- a/hledger_journal.5
+++ b/hledger_journal.5
@@ -1,34 +1,36 @@
 .\"t
 
-.TH "hledger_journal" "5" "December 2018" "hledger 1.12" "hledger User Manuals"
+.TH "hledger_journal" "5" "February 2019" "hledger 1.13" "hledger User Manuals"
 
 
 
 .SH NAME
 .PP
-Journal \- hledger's default file format, representing a General Journal
+Journal \- hledger\[aq]s default file format, representing a General
+Journal
 .SH DESCRIPTION
 .PP
-hledger's usual data source is a plain text file containing journal
+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's not required.
+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'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.
+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's an example:
+Here\[aq]s an example:
 .IP
 .nf
 \f[C]
@@ -81,7 +83,7 @@
 semicolon until end of line)
 .PP
 Then comes zero or more (but usually at least 2) indented lines
-representing\&...
+representing...
 .SS Postings
 .PP
 A posting is an addition of some amount to, or removal of some amount
@@ -134,12 +136,12 @@
 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.
+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's an example.
+Here\[aq]s an example.
 Note that a secondary date will use the year of the primary date if
 unspecified.
 .IP
@@ -203,14 +205,14 @@
 .fi
 .PP
 DATE should be a simple date; if the year is not specified it will use
-the year of the transaction's date.
+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's earlier, more compact bracketed date syntax is also supported:
-\f[C][DATE]\f[], \f[C][DATE=DATE2]\f[] or \f[C][=DATE2]\f[].
+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
@@ -254,11 +256,11 @@
 \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].
+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's behaviour of also matching
+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
@@ -268,9 +270,8 @@
 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:
+What "uncleared", "pending", and "cleared" actually mean is up to you.
+Here\[aq]s one suggestion:
 .PP
 .TS
 tab(@);
@@ -304,10 +305,10 @@
 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.
+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
@@ -380,8 +381,8 @@
 .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]).
+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.
@@ -400,8 +401,8 @@
 .IP \[bu] 2
 scientific E\-notation is allowed.
 Be careful not to use a digit group separator character in scientific
-notation, as it's not supported and it might get mistaken for a decimal
-point.
+notation, as it\[aq]s not supported and it might get mistaken for a
+decimal point.
 (Declaring the digit group separator character explicitly with a
 commodity directive will prevent this.)
 .PP
@@ -439,13 +440,13 @@
 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 \f[C]D\f[] directives usually don't affect
-amount format inference, but in some situations they can do so
+Price amounts and amounts in \f[C]D\f[] directives usually don\[aq]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.
+(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
@@ -456,7 +457,7 @@
 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
+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
@@ -490,7 +491,8 @@
 .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.
+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
@@ -515,7 +517,7 @@
 troubleshooting or for reading Ledger files.
 .SS Assertions and ordering
 .PP
-hledger sorts an account's postings and assertions first by date and
+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.
@@ -534,31 +536,31 @@
 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.
+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't work well across files specified with multiple
-\-f options.
+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's balance within the
+fact the assertion checks only this commodity\[aq]s balance within the
 (possibly multi\-commodity) account balance.
 .PD 0
 .P
 .PD
 This is how assertions work in Ledger also.
-We could call this a \[lq]partial\[rq] balance assertion.
+We could call this a "partial" balance assertion.
 .PP
 To assert the balance of more than one commodity in an account, you can
-write multiple postings, each asserting one commodity's balance.
+write multiple postings, each asserting one commodity\[aq]s balance.
 .PP
 You can make a stronger kind of balance assertion, by writing a double
 equals sign (\f[C]==EXPECTEDBALANCE\f[]).
-This \[lq]complete\[rq] balance assertion asserts the absence of other
+This "complete" balance assertion asserts the absence of other
 commodities (or, that their balance is 0, which to hledger is
 equivalent.)
 .IP
@@ -581,8 +583,8 @@
 \f[]
 .fi
 .PP
-It's not yet possible to make a complete assertion about a balance that
-has multiple commodities.
+It\[aq]s not yet possible to make a complete assertion about a balance
+that has multiple commodities.
 One workaround is to isolate each commodity into its own subaccount:
 .IP
 .nf
@@ -598,10 +600,27 @@
 \ \ a:euro\ \ \ 0\ ==\ \ 1€
 \f[]
 .fi
+.SS Assertions and prices
+.PP
+Balance assertions ignore transaction prices, and should normally be
+written without one:
+.IP
+.nf
+\f[C]
+2019/1/1
+\ \ (a)\ \ \ \ \ $1\ \@\ €1\ =\ $1
+\f[]
+.fi
+.PP
+We do allow prices to be written there, however, and print shows them,
+even though they don\[aq]t affect whether the assertion passes or fails.
+This is for backward compatibility (hledger\[aq]s close command used to
+generate balance assertions with prices), and because balance
+\f[I]assignments\f[] do use them (see below).
 .SS Assertions and subaccounts
 .PP
 Balance assertions do not count the balance from subaccounts; they check
-the posted account's exclusive balance.
+the posted account\[aq]s exclusive balance.
 For example:
 .IP
 .nf
@@ -613,7 +632,7 @@
 \f[]
 .fi
 .PP
-The balance report's flat mode shows these exclusive balances more
+The balance report\[aq]s flat mode shows these exclusive balances more
 clearly:
 .IP
 .nf
@@ -631,6 +650,13 @@
 virtual.
 They are not affected by the \f[C]\-\-real/\-R\f[] flag or
 \f[C]real:\f[] query.
+.SS Assertions and precision
+.PP
+Balance assertions compare the exactly calculated amounts, which are not
+always what is shown by reports.
+Eg a commodity directive may limit the display precision, but this will
+not affect balance assertions.
+Balance assertion failure messages show exact amounts.
 .SS Balance Assignments
 .PP
 Ledger\-style balance assignments are also supported.
@@ -662,16 +688,35 @@
 \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
+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 Balance assignments and prices
+.PP
+A transaction price in a balance assignment will cause the calculated
+amount to have that price attached:
+.IP
+.nf
+\f[C]
+2019/1/1
+\ \ (a)\ \ \ \ \ \ \ \ \ \ \ \ \ =\ $1\ \@\ €2
+\f[]
+.fi
+.IP
+.nf
+\f[C]
+$\ hledger\ print\ \-\-explicit
+2019/01/01
+\ \ \ \ (a)\ \ \ \ \ \ \ \ \ $1\ \@\ €2\ =\ $1\ \@\ €2
+\f[]
+.fi
 .SS Transaction prices
 .PP
-Within a transaction, you can note an amount's price in another
+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).
@@ -725,8 +770,8 @@
 \f[C]{=UNITPRICE}\f[], which hledger currently ignores).
 .PP
 Use the \f[C]\-B/\-\-cost\f[] flag to convert amounts to their
-transaction price's commodity, if any.
-(mnemonic: \[lq]B\[rq] is from \[lq]cost Basis\[rq], as in Ledger).
+transaction price\[aq]s commodity, if any.
+(mnemonic: "B" is from "cost Basis", as in Ledger).
 Eg here is how \-B affects the balance report for the example above:
 .IP
 .nf
@@ -743,7 +788,7 @@
 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
+So if example 3\[aq]s postings are reversed, while the transaction is
 equivalent, \-B shows something different:
 .IP
 .nf
@@ -826,7 +871,8 @@
 \f[]
 .fi
 .PP
-Note this means hledger's tag values can not contain commas or newlines.
+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
@@ -838,13 +884,12 @@
 .PP
 Here,
 .IP \[bu] 2
-\[lq]\f[C]a\ comment\ containing\f[]\[rq] is just comment text, not a
-tag
+"\f[C]a\ comment\ containing\f[]" is just comment text, not a tag
 .IP \[bu] 2
-\[lq]\f[C]tag1\f[]\[rq] is a tag with no value
+"\f[C]tag1\f[]" 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]
+"\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.
@@ -860,18 +905,19 @@
 \f[]
 .fi
 .PP
-Tags are like Ledger's metadata feature, except hledger's tag values are
-simple strings.
+Tags are like Ledger\[aq]s metadata feature, except hledger\[aq]s tag
+values are simple strings.
 .SS Directives
 .PP
 A directive is a line in the journal beginning with a special keyword,
 that influences how the journal is processed.
-hledger's directives are based on a subset of Ledger's, but there are
-many differences (and also some differences between hledger versions).
+hledger\[aq]s directives are based on a subset of Ledger\[aq]s, but
+there are many differences (and also some differences between hledger
+versions).
 .PP
-Directives' behaviour and interactions can get a little bit complex, so
-here is a table summarising the directives and their effects, with links
-to more detailed docs.
+Directives\[aq] behaviour and interactions can get a little bit complex,
+so here is a table summarising the directives and their effects, with
+links to more detailed docs.
 .PP
 .TS
 tab(@);
@@ -1053,8 +1099,8 @@
 It can include journal, timeclock or timedot files, but not CSV files.
 .SS Default year
 .PP
-You can set a default year to be used for subsequent dates which don't
-specify a year.
+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
@@ -1094,7 +1140,7 @@
 \f[]
 .fi
 .PP
-or on multiple lines, using the \[lq]format\[rq] subdirective.
+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
@@ -1123,7 +1169,7 @@
 .PP
 The \f[C]D\f[] 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
+(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 \f[C]D\f[] directive.
 .IP
@@ -1145,9 +1191,9 @@
 .PP
 The \f[C]P\f[] directive declares a market price, which is an exchange
 rate between two commodities on a certain date.
-(In Ledger, they are called \[lq]historical prices\[rq].) These are
-often obtained from a stock exchange, cryptocurrency exchange, or the
-foreign exchange market.
+(In Ledger, they are called "historical prices".) These are often
+obtained from a stock exchange, cryptocurrency exchange, or the foreign
+exchange market.
 .PP
 Here is the format:
 .IP
@@ -1178,8 +1224,7 @@
 to another commodity using these prices.
 .SS Declaring accounts
 .PP
-\f[C]account\f[] directives can be used to pre\-declare some or all
-accounts.
+\f[C]account\f[] directives can be used to pre\-declare accounts.
 Though not required, they can provide several benefits:
 .IP \[bu] 2
 They can document your intended chart of accounts, providing a
@@ -1188,7 +1233,7 @@
 They can store extra information about accounts (account numbers, notes,
 etc.)
 .IP \[bu] 2
-They can help hledger know your accounts' types (asset, liability,
+They can help hledger know your accounts\[aq] types (asset, liability,
 equity, revenue, expense), useful for reports like balancesheet and
 incomestatement.
 .IP \[bu] 2
@@ -1198,41 +1243,89 @@
 They help with account name completion in the add command,
 hledger\-iadd, hledger\-web, ledger\-mode etc.
 .PP
-Here is the full syntax:
+The simplest form is just the word \f[C]account\f[] followed by a
+hledger\-style account name, eg:
 .IP
 .nf
 \f[C]
-account\ ACCTNAME\ \ [ACCTTYPE]
-\ \ [COMMENTS]
+account\ assets:bank:checking
 \f[]
 .fi
+.SS Account comments
 .PP
-The simplest form just declares a hledger\-style account name, eg:
+Comments, beginning with a semicolon, optionally including tags, can be
+written after the account name, and/or on following lines.
+Eg:
 .IP
 .nf
 \f[C]
+account\ assets:bank:checking\ \ ;\ a\ comment
+\ \ ;\ another\ comment
+\ \ ;\ acctno:12345,\ a\ tag
+\f[]
+.fi
+.PP
+Tip: comments on the same line require hledger 1.12+.
+If you need your journal to be compatible with older hledger versions,
+write comments on the next line instead.
+.SS Account subdirectives
+.PP
+We also allow (and ignore) Ledger\-style indented subdirectives, just
+for compatibility.:
+.IP
+.nf
+\f[C]
 account\ assets:bank:checking
+\ \ format\ blah\ blah\ \ ;\ <\-\ subdirective,\ ignored
 \f[]
 .fi
+.PP
+Here is the full syntax of account directives:
+.IP
+.nf
+\f[C]
+account\ ACCTNAME\ \ [ACCTTYPE]\ [;COMMENT]
+\ \ [;COMMENTS]
+\ \ [LEDGER\-STYLE\ SUBDIRECTIVES,\ IGNORED]
+\f[]
+.fi
 .SS Account types
 .PP
-hledger recognises five types of account: asset, liability, equity,
-revenue, expense.
-This is useful for certain accounting\-aware reports, in particular
-balancesheet, incomestatement and cashflow.
+hledger recognises five types (or classes) of account: Asset, Liability,
+Equity, Revenue, Expense.
+This is used by a few accounting\-aware reports such as balancesheet,
+incomestatement and cashflow.
+.SS Auto\-detected account types
 .PP
 If you name your top\-level accounts with some variation of
 \f[C]assets\f[], \f[C]liabilities\f[]/\f[C]debts\f[], \f[C]equity\f[],
 \f[C]revenues\f[]/\f[C]income\f[], or \f[C]expenses\f[], their types are
 detected automatically.
+.SS Account types declared with tags
 .PP
-More generally, you can declare an account's type by adding one of the
-letters \f[C]ALERX\f[] to its account directive, separated from the
-account name by two or more spaces.
-Eg:
+More generally, you can declare an account\[aq]s type with an account
+directive, by writing a \f[C]type:\f[] tag in a comment, followed by one
+of the words \f[C]Asset\f[], \f[C]Liability\f[], \f[C]Equity\f[],
+\f[C]Revenue\f[], \f[C]Expense\f[], or one of the letters \f[C]ALERX\f[]
+(case insensitive):
 .IP
 .nf
 \f[C]
+account\ assets\ \ \ \ \ \ \ ;\ type:Asset
+account\ liabilities\ \ ;\ type:Liability
+account\ equity\ \ \ \ \ \ \ ;\ type:Equity
+account\ revenues\ \ \ \ \ ;\ type:Revenue
+account\ expenses\ \ \ \ \ ;\ type:Expenses
+\f[]
+.fi
+.SS Account types declared with account type codes
+.PP
+Or, you can write one of those letters separated from the account name
+by two or more spaces, but this should probably be considered deprecated
+as of hledger 1.13:
+.IP
+.nf
+\f[C]
 account\ assets\ \ \ \ \ \ \ A
 account\ liabilities\ \ L
 account\ equity\ \ \ \ \ \ \ E
@@ -1240,46 +1333,29 @@
 account\ expenses\ \ \ \ \ X
 \f[]
 .fi
+.SS Overriding auto\-detected types
 .PP
-Note: if you ever override the types of those auto\-detected english
-account names mentioned above, you might need to help the reports a bit:
+If you ever override the types of those auto\-detected english account
+names mentioned above, you might need to help the reports a bit.
+Eg:
 .IP
 .nf
 \f[C]
-;\ make\ "liabilities"\ not\ have\ the\ liability\ type,\ who\ knows\ why
-account\ liabilities\ \ \ E
+;\ make\ "liabilities"\ not\ have\ the\ liability\ type\ \-\ who\ knows\ why
+account\ liabilities\ \ \ ;\ type:E
 
-;\ better\ ensure\ some\ other\ account\ has\ the\ liability\ type,\ 
+;\ we\ need\ to\ ensure\ some\ other\ account\ has\ the\ liability\ type,\ 
 ;\ otherwise\ balancesheet\ would\ still\ show\ "liabilities"\ under\ Liabilities\ 
-account\ \-\ \ \ \ \ \ \ \ \ \ \ \ \ L
-\f[]
-.fi
-.PP
-)
-.SS Account comments
-.PP
-An account directive can also have indented comments on following lines,
-eg:
-.IP
-.nf
-\f[C]
-account\ assets:bank:checking
-\ \ ;\ acctno:12345
-\ \ ;\ a\ comment
+account\ \-\ \ \ \ \ \ \ \ \ \ \ \ \ ;\ type:L
 \f[]
 .fi
-.PP
-We also allow (and ignore) Ledger\-style subdirectives, with no leading
-semicolon, for compatibility.
-.PP
-Tags in account comments, like \f[C]acctno\f[] above, currently have no
-effect.
 .SS Account display order
 .PP
-Account directives also set the order in which accounts are displayed in
-reports, the hledger\-ui accounts screen, the hledger\-web sidebar, etc.
-Normally accounts are listed in alphabetical order, but if you have eg
-these account directives in the journal:
+Account directives also set the order in which accounts are displayed,
+eg in reports, the hledger\-ui accounts screen, and the hledger\-web
+sidebar.
+By default accounts are listed in alphabetical order.
+But if you have these account directives in the journal:
 .IP
 .nf
 \f[C]
@@ -1291,7 +1367,7 @@
 \f[]
 .fi
 .PP
-you'll see those accounts listed in declaration order, not
+you\[aq]ll see those accounts displayed in declaration order, not
 alphabetically:
 .IP
 .nf
@@ -1317,13 +1393,14 @@
 \f[]
 .fi
 .PP
-would influence the position of \f[C]zoo\f[] among \f[C]other\f[]'s
+would influence the position of \f[C]zoo\f[] among \f[C]other\f[]\[aq]s
 subaccounts, but not the position of \f[C]other\f[] among the top\-level
 accounts.
 This means: \- you will sometimes declare parent accounts (eg
-\f[C]account\ other\f[] above) that you don't intend to post to, just to
-customize their display order \- sibling accounts stay together (you
-couldn't display \f[C]x:y\f[] in between \f[C]a:b\f[] and \f[C]a:c\f[]).
+\f[C]account\ other\f[] above) that you don\[aq]t intend to post to,
+just to customize their display order \- sibling accounts stay together
+(you couldn\[aq]t display \f[C]x:y\f[] in between \f[C]a:b\f[] and
+\f[C]a:c\f[]).
 .SS Rewriting accounts
 .PP
 You can define account alias rules which rewrite your account names, or
@@ -1362,7 +1439,7 @@
 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.
+It\[aq]s useful for trying out aliases interactively.
 .PP
 OLD and NEW are case sensitive full account names.
 hledger will replace any occurrence of the old account name with the new
@@ -1508,23 +1585,22 @@
 .PP
 Partial or relative dates (M/D, D, tomorrow, last week) in the period
 expression can work (useful or not).
-They will be relative to today's date, unless a Y default year directive
-is in effect, in which case they will be relative to Y/1/1.
+They will be relative to today\[aq]s date, unless a Y default year
+directive is in effect, in which case they will be relative to Y/1/1.
+.SS Two spaces after the period expression
 .PP
-Period expressions must be terminated by \f[B]two or more spaces\f[] if
-followed by additional fields.
-For example, the periodic transaction given below includes a transaction
-description \[lq]paycheck\[rq], which is separated from the period
-expression by a double space.
-If not for the second space, hledger would attempt (and fail) to parse
-\[lq]paycheck\[rq] as a part of the period expression.
+If the period expression is followed by a transaction description, these
+must be separated by \f[B]two or more spaces\f[].
+This helps hledger know where the period expression ends, so that
+descriptions can not accidentally alter their meaning, as in this
+example:
 .IP
 .nf
 \f[C]
-;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 2\ or\ more\ spaces
-;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ||
-;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ vv
-~\ every\ 2\ weeks\ from\ 2018/6/4\ to\ 2018/9\ \ paycheck
+;\ 2\ or\ more\ spaces\ needed\ here,\ so\ the\ period\ is\ not\ understood\ as\ "every\ 2\ months\ in\ 2020"
+;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ||
+;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ vv
+~\ every\ 2\ months\ \ in\ 2020,\ we\ will\ review
 \ \ \ \ assets:bank:checking\ \ \ $1500
 \ \ \ \ income:acme\ inc
 \f[]
@@ -1553,9 +1629,9 @@
 ends on the report end date if specified with \-e/\-p/date:, or 180 days
 from today.
 .PP
-where \[lq]today\[rq] means the current date at report time.
-The \[lq]later of\[rq] rule ensures that forecast transactions do not
-overlap normal transactions in time; they will begin only after normal
+where "today" means the current date at report time.
+The "later of" rule ensures that forecast transactions do not overlap
+normal transactions in time; they will begin only after normal
 transactions end.
 .PP
 Forecasting can be useful for estimating balances into the future, and
@@ -1583,18 +1659,19 @@
 For more details, see: balance: Budget report and Cookbook: Budgeting
 and Forecasting.
 .PP
-.SS Transaction Modifiers
+.SS Transaction modifiers
 .PP
 Transaction modifier rules describe changes that should be applied
 automatically to certain transactions.
-Currently, this means adding extra postings (also known as
-\[lq]automated postings\[rq]).
-Transaction modifiers are enabled by the \f[C]\-\-auto\f[] flag.
+They can be enabled by using the \f[C]\-\-auto\f[] flag.
+Currently, just one kind of change is possible: adding extra postings.
+These rule\-generated postings are known as "automated postings" or
+"auto postings".
 .PP
 A transaction modifier rule looks quite like a normal transaction,
 except the first line is an equals sign followed by a query that matches
 certain postings (mnemonic: \f[C]=\f[] suggests matching).
-And each \[lq]posting\[rq] is actually a posting\-generating rule:
+And each "posting" is actually a posting\-generating rule:
 .IP
 .nf
 \f[C]
@@ -1605,8 +1682,7 @@
 \f[]
 .fi
 .PP
-The posting rules look just like normal postings, except the amount can
-be:
+These posting rules look like normal postings, except the amount can be:
 .IP \[bu] 2
 a normal amount with a commodity symbol, eg \f[C]$2\f[].
 This will be used as\-is.
@@ -1616,13 +1692,13 @@
 this.
 .IP \[bu] 2
 a numeric multiplier, eg \f[C]*2\f[] (a star followed by a number N).
-The matched posting's amount (and total price, if any) will be
+The matched posting\[aq]s amount (and total price, if any) will be
 multiplied by N.
 .IP \[bu] 2
 a multiplier with a commodity symbol, eg \f[C]*$2\f[] (a star, number N,
 and symbol S).
-The matched posting's amount will be multiplied by N, and its commodity
-symbol will be replaced with S.
+The matched posting\[aq]s amount will be multiplied by N, and its
+commodity symbol will be replaced with S.
 .PP
 Some examples:
 .IP
@@ -1662,10 +1738,19 @@
 \ \ \ \ assets:checking\ \ \ \ \ \ \ \ \ \ \ \ $20
 \f[]
 .fi
+.SS Auto postings and transaction balancing / inferred amounts / balance
+assertions
 .PP
-Postings added by transaction modifiers participate in transaction
-balancing, missing amount inference and balance assertions, like regular
-postings.
+Currently, transaction modifiers are applied / auto postings are added:
+.IP \[bu] 2
+after missing amounts are inferred, and transactions are checked for
+balancedness,
+.IP \[bu] 2
+but before balance assertions are checked.
+.PP
+Note this means that journal entries must be balanced both before and
+after auto postings are added.
+This changed in hledger 1.12+; see #893 for background.
 .SH EDITOR SUPPORT
 .PP
 Add\-on modes exist for various text editors, to make working with
diff --git a/hledger_journal.info b/hledger_journal.info
--- a/hledger_journal.info
+++ b/hledger_journal.info
@@ -4,7 +4,7 @@
 
 File: hledger_journal.info,  Node: Top,  Next: FILE FORMAT,  Up: (dir)
 
-hledger_journal(5) hledger 1.12
+hledger_journal(5) hledger 1.13
 *******************************
 
 hledger's usual data source is a plain text file containing journal
@@ -82,7 +82,7 @@
 * Tags::
 * Directives::
 * Periodic transactions::
-* Transaction Modifiers::
+* Transaction modifiers::
 
 
 File: hledger_journal.info,  Node: Transactions,  Next: Postings,  Up: FILE FORMAT
@@ -473,8 +473,10 @@
 * Assertions and included files::
 * Assertions and multiple -f options::
 * Assertions and commodities::
+* Assertions and prices::
 * Assertions and subaccounts::
 * Assertions and virtual postings::
+* Assertions and precision::
 
 
 File: hledger_journal.info,  Node: Assertions and ordering,  Next: Assertions and included files,  Up: Balance Assertions
@@ -517,7 +519,7 @@
 -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
+File: hledger_journal.info,  Node: Assertions and commodities,  Next: Assertions and prices,  Prev: Assertions and multiple -f options,  Up: Balance Assertions
 
 1.9.4 Assertions and commodities
 --------------------------------
@@ -566,9 +568,27 @@
   a:euro   0 ==  1€
 
 
-File: hledger_journal.info,  Node: Assertions and subaccounts,  Next: Assertions and virtual postings,  Prev: Assertions and commodities,  Up: Balance Assertions
+File: hledger_journal.info,  Node: Assertions and prices,  Next: Assertions and subaccounts,  Prev: Assertions and commodities,  Up: Balance Assertions
 
-1.9.5 Assertions and subaccounts
+1.9.5 Assertions and prices
+---------------------------
+
+Balance assertions ignore transaction prices, and should normally be
+written without one:
+
+2019/1/1
+  (a)     $1 @ €1 = $1
+
+   We do allow prices to be written there, however, and print shows
+them, even though they don't affect whether the assertion passes or
+fails.  This is for backward compatibility (hledger's close command used
+to generate balance assertions with prices), and because balance
+_assignments_ do use them (see below).
+
+
+File: hledger_journal.info,  Node: Assertions and subaccounts,  Next: Assertions and virtual postings,  Prev: Assertions and prices,  Up: Balance Assertions
+
+1.9.6 Assertions and subaccounts
 --------------------------------
 
 Balance assertions do not count the balance from subaccounts; they check
@@ -589,9 +609,9 @@
                    2
 
 
-File: hledger_journal.info,  Node: Assertions and virtual postings,  Prev: Assertions and subaccounts,  Up: Balance Assertions
+File: hledger_journal.info,  Node: Assertions and virtual postings,  Next: Assertions and precision,  Prev: Assertions and subaccounts,  Up: Balance Assertions
 
-1.9.6 Assertions and virtual postings
+1.9.7 Assertions and virtual postings
 -------------------------------------
 
 Balance assertions are checked against all postings, both real and
@@ -599,6 +619,17 @@
 query.
 
 
+File: hledger_journal.info,  Node: Assertions and precision,  Prev: Assertions and virtual postings,  Up: Balance Assertions
+
+1.9.8 Assertions and precision
+------------------------------
+
+Balance assertions compare the exactly calculated amounts, which are not
+always what is shown by reports.  Eg a commodity directive may limit the
+display precision, but this will not affect balance assertions.  Balance
+assertion failure messages show exact amounts.
+
+
 File: hledger_journal.info,  Node: Balance Assignments,  Next: Transaction prices,  Prev: Balance Assertions,  Up: FILE FORMAT
 
 1.10 Balance Assignments
@@ -630,8 +661,27 @@
 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.
+* Menu:
 
+* Balance assignments and prices::
+
 
+File: hledger_journal.info,  Node: Balance assignments and prices,  Up: Balance Assignments
+
+1.10.1 Balance assignments and prices
+-------------------------------------
+
+A transaction price in a balance assignment will cause the calculated
+amount to have that price attached:
+
+2019/1/1
+  (a)             = $1 @ €2
+
+$ hledger print --explicit
+2019/01/01
+    (a)         $1 @ €2 = $1 @ €2
+
+
 File: hledger_journal.info,  Node: Transaction prices,  Next: Comments,  Prev: Balance Assignments,  Up: FILE FORMAT
 
 1.11 Transaction prices
@@ -1033,8 +1083,8 @@
 1.14.7 Declaring accounts
 -------------------------
 
-'account' directives can be used to pre-declare some or all accounts.
-Though not required, they can provide several benefits:
+'account' directives can be used to pre-declare accounts.  Though not
+required, they can provide several benefits:
 
    * They can document your intended chart of accounts, providing a
      reference.
@@ -1048,86 +1098,108 @@
    * They help with account name completion in the add command,
      hledger-iadd, hledger-web, ledger-mode etc.
 
-   Here is the full syntax:
-
-account ACCTNAME  [ACCTTYPE]
-  [COMMENTS]
-
-   The simplest form just declares a hledger-style account name, eg:
+   The simplest form is just the word 'account' followed by a
+hledger-style account name, eg:
 
 account assets:bank:checking
 
 * Menu:
 
-* Account types::
 * Account comments::
+* Account subdirectives::
+* Account types::
 * Account display order::
 
 
-File: hledger_journal.info,  Node: Account types,  Next: Account comments,  Up: Declaring accounts
+File: hledger_journal.info,  Node: Account comments,  Next: Account subdirectives,  Up: Declaring accounts
 
-1.14.7.1 Account types
-......................
+1.14.7.1 Account comments
+.........................
 
-hledger recognises five types of account: asset, liability, equity,
-revenue, expense.  This is useful for certain accounting-aware reports,
-in particular balancesheet, incomestatement and cashflow.
+Comments, beginning with a semicolon, optionally including tags, can be
+written after the account name, and/or on following lines.  Eg:
 
-   If you name your top-level accounts with some variation of 'assets',
-'liabilities'/'debts', 'equity', 'revenues'/'income', or 'expenses',
-their types are detected automatically.
+account assets:bank:checking  ; a comment
+  ; another comment
+  ; acctno:12345, a tag
 
-   More generally, you can declare an account's type by adding one of
-the letters 'ALERX' to its account directive, separated from the account
-name by two or more spaces.  Eg:
+   Tip: comments on the same line require hledger 1.12+.  If you need
+your journal to be compatible with older hledger versions, write
+comments on the next line instead.
 
-account assets       A
-account liabilities  L
-account equity       E
-account revenues     R
-account expenses     X
+
+File: hledger_journal.info,  Node: Account subdirectives,  Next: Account types,  Prev: Account comments,  Up: Declaring accounts
 
-   Note: if you ever override the types of those auto-detected english
-account names mentioned above, you might need to help the reports a bit:
+1.14.7.2 Account subdirectives
+..............................
 
-; make "liabilities" not have the liability type, who knows why
-account liabilities   E
+We also allow (and ignore) Ledger-style indented subdirectives, just for
+compatibility.:
 
-; better ensure some other account has the liability type, 
-; otherwise balancesheet would still show "liabilities" under Liabilities 
-account -             L
+account assets:bank:checking
+  format blah blah  ; <- subdirective, ignored
 
-   )
+   Here is the full syntax of account directives:
 
+account ACCTNAME  [ACCTTYPE] [;COMMENT]
+  [;COMMENTS]
+  [LEDGER-STYLE SUBDIRECTIVES, IGNORED]
+
 
-File: hledger_journal.info,  Node: Account comments,  Next: Account display order,  Prev: Account types,  Up: Declaring accounts
+File: hledger_journal.info,  Node: Account types,  Next: Account display order,  Prev: Account subdirectives,  Up: Declaring accounts
 
-1.14.7.2 Account comments
-.........................
+1.14.7.3 Account types
+......................
 
-An account directive can also have indented comments on following lines,
-eg:
+hledger recognises five types (or classes) of account: Asset, Liability,
+Equity, Revenue, Expense.  This is used by a few accounting-aware
+reports such as balancesheet, incomestatement and cashflow.
+Auto-detected account types If you name your top-level accounts with
+some variation of 'assets', 'liabilities'/'debts', 'equity',
+'revenues'/'income', or 'expenses', their types are detected
+automatically.  Account types declared with tags More generally, you can
+declare an account's type with an account directive, by writing a
+'type:' tag in a comment, followed by one of the words 'Asset',
+'Liability', 'Equity', 'Revenue', 'Expense', or one of the letters
+'ALERX' (case insensitive):
 
-account assets:bank:checking
-  ; acctno:12345
-  ; a comment
+account assets       ; type:Asset
+account liabilities  ; type:Liability
+account equity       ; type:Equity
+account revenues     ; type:Revenue
+account expenses     ; type:Expenses
 
-   We also allow (and ignore) Ledger-style subdirectives, with no
-leading semicolon, for compatibility.
+   Account types declared with account type codes Or, you can write one
+of those letters separated from the account name by two or more spaces,
+but this should probably be considered deprecated as of hledger 1.13:
 
-   Tags in account comments, like 'acctno' above, currently have no
-effect.
+account assets       A
+account liabilities  L
+account equity       E
+account revenues     R
+account expenses     X
 
+   Overriding auto-detected types If you ever override the types of
+those auto-detected english account names mentioned above, you might
+need to help the reports a bit.  Eg:
+
+; make "liabilities" not have the liability type - who knows why
+account liabilities   ; type:E
+
+; we need to ensure some other account has the liability type, 
+; otherwise balancesheet would still show "liabilities" under Liabilities 
+account -             ; type:L
+
 
-File: hledger_journal.info,  Node: Account display order,  Prev: Account comments,  Up: Declaring accounts
+File: hledger_journal.info,  Node: Account display order,  Prev: Account types,  Up: Declaring accounts
 
-1.14.7.3 Account display order
+1.14.7.4 Account display order
 ..............................
 
-Account directives also set the order in which accounts are displayed in
-reports, the hledger-ui accounts screen, the hledger-web sidebar, etc.
-Normally accounts are listed in alphabetical order, but if you have eg
-these account directives in the journal:
+Account directives also set the order in which accounts are displayed,
+eg in reports, the hledger-ui accounts screen, and the hledger-web
+sidebar.  By default accounts are listed in alphabetical order.  But if
+you have these account directives in the journal:
 
 account assets
 account liabilities
@@ -1135,7 +1207,7 @@
 account revenues
 account expenses
 
-   you'll see those accounts listed in declaration order, not
+   you'll see those accounts displayed in declaration order, not
 alphabetically:
 
 $ hledger accounts -1
@@ -1306,7 +1378,7 @@
 parent account.
 
 
-File: hledger_journal.info,  Node: Periodic transactions,  Next: Transaction Modifiers,  Prev: Directives,  Up: FILE FORMAT
+File: hledger_journal.info,  Node: Periodic transactions,  Next: Transaction modifiers,  Prev: Directives,  Up: FILE FORMAT
 
 1.15 Periodic transactions
 ==========================
@@ -1332,32 +1404,36 @@
 expression can work (useful or not).  They will be relative to today's
 date, unless a Y default year directive is in effect, in which case they
 will be relative to Y/1/1.
-
-   Period expressions must be terminated by *two or more spaces* if
-followed by additional fields.  For example, the periodic transaction
-given below includes a transaction description "paycheck", which is
-separated from the period expression by a double space.  If not for the
-second space, hledger would attempt (and fail) to parse "paycheck" as a
-part of the period expression.
-
-;                                2 or more spaces
-;                                      ||
-;                                      vv
-~ every 2 weeks from 2018/6/4 to 2018/9  paycheck
-    assets:bank:checking   $1500
-    income:acme inc
-
 * Menu:
 
+* Two spaces after the period expression::
 * Forecasting with periodic transactions::
 * Budgeting with periodic transactions::
 
 
-File: hledger_journal.info,  Node: Forecasting with periodic transactions,  Next: Budgeting with periodic transactions,  Up: Periodic transactions
+File: hledger_journal.info,  Node: Two spaces after the period expression,  Next: Forecasting with periodic transactions,  Up: Periodic transactions
 
-1.15.1 Forecasting with periodic transactions
+1.15.1 Two spaces after the period expression
 ---------------------------------------------
 
+If the period expression is followed by a transaction description, these
+must be separated by *two or more spaces*.  This helps hledger know
+where the period expression ends, so that descriptions can not
+accidentally alter their meaning, as in this example:
+
+; 2 or more spaces needed here, so the period is not understood as "every 2 months in 2020"
+;               ||
+;               vv
+~ every 2 months  in 2020, we will review
+    assets:bank:checking   $1500
+    income:acme inc
+
+
+File: hledger_journal.info,  Node: Forecasting with periodic transactions,  Next: Budgeting with periodic transactions,  Prev: Two spaces after the period expression,  Up: Periodic transactions
+
+1.15.2 Forecasting with periodic transactions
+---------------------------------------------
+
 With the '--forecast' flag, each periodic transaction rule generates
 future transactions recurring at the specified interval.  These are not
 saved in the journal, but appear in all reports.  They will look like
@@ -1398,7 +1474,7 @@
 
 File: hledger_journal.info,  Node: Budgeting with periodic transactions,  Prev: Forecasting with periodic transactions,  Up: Periodic transactions
 
-1.15.2 Budgeting with periodic transactions
+1.15.3 Budgeting with periodic transactions
 -------------------------------------------
 
 With the '--budget' flag, currently supported by the balance command,
@@ -1412,15 +1488,16 @@
 and Forecasting.
 
 
-File: hledger_journal.info,  Node: Transaction Modifiers,  Prev: Periodic transactions,  Up: FILE FORMAT
+File: hledger_journal.info,  Node: Transaction modifiers,  Prev: Periodic transactions,  Up: FILE FORMAT
 
-1.16 Transaction Modifiers
+1.16 Transaction modifiers
 ==========================
 
 Transaction modifier rules describe changes that should be applied
-automatically to certain transactions.  Currently, this means adding
-extra postings (also known as "automated postings").  Transaction
-modifiers are enabled by the '--auto' flag.
+automatically to certain transactions.  They can be enabled by using the
+'--auto' flag.  Currently, just one kind of change is possible: adding
+extra postings.  These rule-generated postings are known as "automated
+postings" or "auto postings".
 
    A transaction modifier rule looks quite like a normal transaction,
 except the first line is an equals sign followed by a query that matches
@@ -1432,8 +1509,8 @@
     ACCT  [AMT]
     ...
 
-   The posting rules look just like normal postings, except the amount
-can be:
+   These posting rules look like normal postings, except the amount can
+be:
 
    * a normal amount with a commodity symbol, eg '$2'.  This will be
      used as-is.
@@ -1477,11 +1554,28 @@
     assets:checking:gifts     -$20
     assets:checking            $20
 
-   Postings added by transaction modifiers participate in transaction
-balancing, missing amount inference and balance assertions, like regular
-postings.
+* Menu:
 
+* Auto postings and transaction balancing / inferred amounts / balance assertions::
+
 
+File: hledger_journal.info,  Node: Auto postings and transaction balancing / inferred amounts / balance assertions,  Up: Transaction modifiers
+
+1.16.1 Auto postings and transaction balancing / inferred amounts /
+-------------------------------------------------------------------
+
+balance assertions Currently, transaction modifiers are applied / auto
+postings are added:
+
+   * after missing amounts are inferred, and transactions are checked
+     for balancedness,
+   * but before balance assertions are checked.
+
+   Note this means that journal entries must be balanced both before and
+after auto postings are added.  This changed in hledger 1.12+; see #893
+for background.
+
+
 File: hledger_journal.info,  Node: EDITOR SUPPORT,  Prev: FILE FORMAT,  Up: Top
 
 2 EDITOR SUPPORT
@@ -1539,69 +1633,81 @@
 Ref: #virtual-postings15185
 Node: Balance Assertions16405
 Ref: #balance-assertions16580
-Node: Assertions and ordering17476
-Ref: #assertions-and-ordering17662
-Node: Assertions and included files18362
-Ref: #assertions-and-included-files18603
-Node: Assertions and multiple -f options18936
-Ref: #assertions-and-multiple--f-options19190
-Node: Assertions and commodities19322
-Ref: #assertions-and-commodities19557
-Node: Assertions and subaccounts20745
-Ref: #assertions-and-subaccounts20977
-Node: Assertions and virtual postings21498
-Ref: #assertions-and-virtual-postings21705
-Node: Balance Assignments21847
-Ref: #balance-assignments22028
-Node: Transaction prices23148
-Ref: #transaction-prices23317
-Node: Comments25585
-Ref: #comments25719
-Node: Tags26889
-Ref: #tags27007
-Node: Directives28409
-Ref: #directives28552
-Node: Comment blocks34159
-Ref: #comment-blocks34304
-Node: Including other files34480
-Ref: #including-other-files34660
-Node: Default year35068
-Ref: #default-year35237
-Node: Declaring commodities35660
-Ref: #declaring-commodities35843
-Node: Default commodity37070
-Ref: #default-commodity37246
-Node: Market prices37882
-Ref: #market-prices38047
-Node: Declaring accounts38888
-Ref: #declaring-accounts39064
-Node: Account types40021
-Ref: #account-types40170
-Node: Account comments41244
-Ref: #account-comments41429
-Node: Account display order41750
-Ref: #account-display-order41923
-Node: Rewriting accounts43045
-Ref: #rewriting-accounts43230
-Node: Basic aliases43964
-Ref: #basic-aliases44110
-Node: Regex aliases44814
-Ref: #regex-aliases44985
-Node: Multiple aliases45703
-Ref: #multiple-aliases45878
-Node: end aliases46376
-Ref: #end-aliases46523
-Node: Default parent account46624
-Ref: #default-parent-account46790
-Node: Periodic transactions47674
-Ref: #periodic-transactions47856
-Node: Forecasting with periodic transactions49559
-Ref: #forecasting-with-periodic-transactions49802
-Node: Budgeting with periodic transactions51489
-Ref: #budgeting-with-periodic-transactions51728
-Node: Transaction Modifiers52187
-Ref: #transaction-modifiers52350
-Node: EDITOR SUPPORT54331
-Ref: #editor-support54449
+Node: Assertions and ordering17531
+Ref: #assertions-and-ordering17717
+Node: Assertions and included files18417
+Ref: #assertions-and-included-files18658
+Node: Assertions and multiple -f options18991
+Ref: #assertions-and-multiple--f-options19245
+Node: Assertions and commodities19377
+Ref: #assertions-and-commodities19607
+Node: Assertions and prices20795
+Ref: #assertions-and-prices21007
+Node: Assertions and subaccounts21447
+Ref: #assertions-and-subaccounts21674
+Node: Assertions and virtual postings22195
+Ref: #assertions-and-virtual-postings22435
+Node: Assertions and precision22577
+Ref: #assertions-and-precision22768
+Node: Balance Assignments23035
+Ref: #balance-assignments23216
+Node: Balance assignments and prices24380
+Ref: #balance-assignments-and-prices24552
+Node: Transaction prices24776
+Ref: #transaction-prices24945
+Node: Comments27213
+Ref: #comments27347
+Node: Tags28517
+Ref: #tags28635
+Node: Directives30037
+Ref: #directives30180
+Node: Comment blocks35787
+Ref: #comment-blocks35932
+Node: Including other files36108
+Ref: #including-other-files36288
+Node: Default year36696
+Ref: #default-year36865
+Node: Declaring commodities37288
+Ref: #declaring-commodities37471
+Node: Default commodity38698
+Ref: #default-commodity38874
+Node: Market prices39510
+Ref: #market-prices39675
+Node: Declaring accounts40516
+Ref: #declaring-accounts40692
+Node: Account comments41617
+Ref: #account-comments41780
+Node: Account subdirectives42175
+Ref: #account-subdirectives42370
+Node: Account types42683
+Ref: #account-types42867
+Node: Account display order44511
+Ref: #account-display-order44681
+Node: Rewriting accounts45810
+Ref: #rewriting-accounts45995
+Node: Basic aliases46729
+Ref: #basic-aliases46875
+Node: Regex aliases47579
+Ref: #regex-aliases47750
+Node: Multiple aliases48468
+Ref: #multiple-aliases48643
+Node: end aliases49141
+Ref: #end-aliases49288
+Node: Default parent account49389
+Ref: #default-parent-account49555
+Node: Periodic transactions50439
+Ref: #periodic-transactions50621
+Node: Two spaces after the period expression51746
+Ref: #two-spaces-after-the-period-expression51991
+Node: Forecasting with periodic transactions52476
+Ref: #forecasting-with-periodic-transactions52766
+Node: Budgeting with periodic transactions54453
+Ref: #budgeting-with-periodic-transactions54692
+Node: Transaction modifiers55151
+Ref: #transaction-modifiers55314
+Node: Auto postings and transaction balancing / inferred amounts / balance assertions57298
+Ref: #auto-postings-and-transaction-balancing-inferred-amounts-balance-assertions57599
+Node: EDITOR SUPPORT57977
+Ref: #editor-support58095
 
 End Tag Table
diff --git a/hledger_journal.txt b/hledger_journal.txt
--- a/hledger_journal.txt
+++ b/hledger_journal.txt
@@ -446,8 +446,21 @@
                 a:usd    0 == $1
                 a:euro   0 ==  1
 
+   Assertions and prices
+       Balance assertions ignore transaction prices, and  should  normally  be
+       written without one:
+
+              2019/1/1
+                (a)     $1 @ 1 = $1
+
+       We  do allow prices to be written there, however, and print shows them,
+       even though they don't affect whether the assertion  passes  or  fails.
+       This  is  for  backward  compatibility (hledger's close command used to
+       generate balance assertions with prices), and because  balance  assign-
+       ments do use them (see below).
+
    Assertions and subaccounts
-       Balance assertions do not count  the  balance  from  subaccounts;  they
+       Balance  assertions  do  not  count  the balance from subaccounts; they
        check the posted account's exclusive balance.  For example:
 
               1/1
@@ -455,7 +468,7 @@
                 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
+       The balance report's flat mode  shows  these  exclusive  balances  more
        clearly:
 
               $ hledger bal checking --flat
@@ -468,6 +481,12 @@
        Balance assertions are checked against all postings, both real and vir-
        tual.  They are not affected by the --real/-R flag or real: query.
 
+   Assertions and precision
+       Balance assertions compare the exactly calculated  amounts,  which  are
+       not  always  what  is  shown  by reports.  Eg a commodity directive may
+       limit the display precision, but this will not  affect  balance  asser-
+       tions.  Balance assertion failure messages show exact amounts.
+
    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
@@ -496,11 +515,22 @@
        less explicit; to know the exact amount posted, you have to run hledger
        or do the calculations yourself, instead of just reading it.
 
+   Balance assignments and prices
+       A transaction price in a balance assignment will cause  the  calculated
+       amount to have that price attached:
+
+              2019/1/1
+                (a)             = $1 @ 2
+
+              $ hledger print --explicit
+              2019/01/01
+                  (a)         $1 @ 2 = $1 @ 2
+
    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.  Note transaction prices are
+       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.  Note  transaction  prices  are
        fixed at the time of the transaction, and do not change over time.  See
        also market prices, which represent prevailing exchange rates on a cer-
        tain date.
@@ -529,7 +559,7 @@
        (Ledger users: Ledger uses a different syntax for fixed prices, {=UNIT-
        PRICE}, which hledger currently ignores).
 
-       Use the -B/--cost flag to convert amounts to their transaction  price's
+       Use  the -B/--cost flag to convert amounts to their transaction price's
        commodity, if any.  (mnemonic: "B" is from "cost Basis", as in Ledger).
        Eg here is how -B affects the balance report for the example above:
 
@@ -540,8 +570,8 @@
                              $-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
+       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:
 
@@ -555,14 +585,14 @@
 
    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
+       (*)  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.)
 
-       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.
+       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:
@@ -586,24 +616,24 @@
                   ; another comment line for posting 2
               ; a file comment (because not indented)
 
-       You can also comment  larger  regions  of  a  file  using  comment  and
+       You  can  also  comment  larger  regions  of  a  file using comment and
        end comment directives.
 
    Tags
-       Tags  are  a  way  to add extra labels or labelled data to postings and
+       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
+       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
+       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-
+       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:
 
@@ -617,78 +647,69 @@
 
        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,
+       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
+       Tags are like Ledger's metadata feature, except  hledger's  tag  values
        are simple strings.
 
    Directives
-       A directive is a line in the journal beginning with a special  keyword,
+       A  directive is a line in the journal beginning with a special keyword,
        that influences how the journal is processed.  hledger's directives are
        based on a subset of Ledger's, but there are many differences (and also
        some differences between hledger versions).
 
        Directives' behaviour and interactions can get a little bit complex, so
-       here is a table summarising the  directives  and  their  effects,  with
+       here  is  a  table  summarising  the directives and their effects, with
        links to more detailed docs.
 
 
-       direc-          end                 subdi-    purpose                        can affect  (as  of
+
+
+
+       direc-          end                 subdi-    purpose                        can  affect  (as of
        tive            directive           rec-                                     2018/06)
                                            tives
        -------------------------------------------------------------------------------------------------
-       account                             any       document   account    names,   all entries in  all
-                                           text      declare account types & dis-   files,   before  or
+       account                             any       document    account   names,   all  entries in all
+                                           text      declare account types & dis-   files,  before   or
                                                      play order                     after
        alias           end aliases                   rewrite account names          following
                                                                                     inline/included
                                                                                     entries  until  end
-                                                                                    of current file  or
+                                                                                    of  current file or
                                                                                     end directive
-       apply account   end apply account             prepend  a  common parent to   following
+       apply account   end apply account             prepend a common  parent  to   following
                                                      account names                  inline/included
                                                                                     entries  until  end
-                                                                                    of  current file or
+                                                                                    of current file  or
                                                                                     end directive
        comment         end comment                   ignore part of journal         following
                                                                                     inline/included
                                                                                     entries  until  end
-                                                                                    of  current file or
+                                                                                    of current file  or
                                                                                     end directive
-       commodity                           format    declare a commodity and  its   number    notation:
+       commodity                           format    declare  a commodity and its   number    notation:
                                                      number  notation  &  display   following   entries
                                                      style                          in  that  commodity
-                                                                                    in  all files; dis-
+                                                                                    in all files;  dis-
                                                                                     play style: amounts
                                                                                     of  that  commodity
                                                                                     in reports
-
-
-
-
-
-
-
-
-
-
-
-
-       D                                             declare a commodity,  number   commodity: all com-
+       D                                             declare  a commodity, number   commodity: all com-
                                                      notation & display style for   modityless  entries
-                                                     commodityless amounts          in all files;  num-
-                                                                                    ber  notation: fol-
+                                                     commodityless amounts          in  all files; num-
+                                                                                    ber notation:  fol-
                                                                                     lowing   commodity-
-                                                                                    less   entries  and
+                                                                                    less  entries   and
                                                                                     entries   in   that
-                                                                                    commodity   in  all
+                                                                                    commodity  in   all
                                                                                     files;      display
                                                                                     style:  amounts  of
                                                                                     that  commodity  in
@@ -699,7 +720,7 @@
                                                      commodity                      commodity        in
                                                                                     reports, when -V is
                                                                                     used
-       Y                                             declare  a year for yearless   following
+       Y                                             declare a year for  yearless   following
                                                      dates                          inline/included
                                                                                     entries  until  end
                                                                                     of current file
@@ -709,9 +730,9 @@
 
        subdirec-   optional indented directive line immediately following a par-
        tive        ent directive
-       number      how to interpret numbers when parsing  journal  entries  (the
-       notation    identity  of  the  decimal  separator character).  (Currently
-                   each commodity can have its own notation, even  in  the  same
+       number      how  to  interpret  numbers when parsing journal entries (the
+       notation    identity of the  decimal  separator  character).   (Currently
+                   each  commodity  can  have its own notation, even in the same
                    file.)
        display     how to display amounts of a commodity in reports (symbol side
        style       and spacing, digit groups, decimal separator, decimal places)
@@ -719,37 +740,37 @@
        scope       are affected by a directive
 
        As you can see, directives vary in which journal entries and files they
-       affect,  and  whether  they  are  focussed on input (parsing) or output
+       affect, and whether they are focussed  on  input  (parsing)  or  output
        (reports).  Some directives have multiple effects.
 
-       If you have a journal made up of multiple files, or  pass  multiple  -f
-       options  on  the  command line, note that directives which affect input
-       typically last only until the end of their defining  file.   This  pro-
+       If  you  have  a journal made up of multiple files, or pass multiple -f
+       options on the command line, note that directives  which  affect  input
+       typically  last  only  until the end of their defining file.  This pro-
        vides more simplicity and predictability, eg reports are not changed by
-       writing file options in a different order.  It  can  be  surprising  at
+       writing  file  options  in  a different order.  It can be surprising at
        times though.
 
    Comment blocks
-       A  line  containing just comment starts a commented region of the file,
+       A line containing just comment starts a commented region of  the  file,
        and a line containing just end comment (or the end of the current file)
        ends it.  See also comments.
 
    Including other files
-       You  can  pull in the content of additional files by writing an include
+       You can pull in the content of additional 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.   The  include  file  path may contain common glob patterns (e.g.
+       If  the path does not begin with a slash, it is relative to the current
+       file.  The include file path may contain  common  glob  patterns  (e.g.
        *).
 
-       The include directive can only  be  used  in  journal  files.   It  can
+       The  include  directive  can  only  be  used  in journal files.  It can
        include journal, timeclock or timedot files, but not CSV files.
 
    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.
+       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
@@ -769,8 +790,8 @@
                 assets
 
    Declaring commodities
-       The  commodity  directive declares commodities which may be used in the
-       journal (though currently we do not enforce this).  It may  be  written
+       The commodity directive declares commodities which may be used  in  the
+       journal  (though  currently we do not enforce this).  It may be written
        on a single line, like this:
 
               ; commodity EXAMPLEAMOUNT
@@ -780,8 +801,8 @@
               ; 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
+       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
@@ -793,19 +814,19 @@
               commodity INR
                 format INR 9,99,99,999.00
 
-       Commodity  directives  have  a second purpose: they define the standard
+       Commodity directives have a second purpose: they  define  the  standard
        display format for amounts in the commodity.  Normally the display for-
-       mat  is  inferred  from journal entries, but this can be unpredictable;
-       declaring it with a commodity  directive  overrides  this  and  removes
-       ambiguity.   Towards  this  end,  amounts  in commodity directives must
-       always be written with a decimal point (a period or comma, followed  by
+       mat is inferred from journal entries, but this  can  be  unpredictable;
+       declaring  it  with  a  commodity  directive overrides this and removes
+       ambiguity.  Towards this end,  amounts  in  commodity  directives  must
+       always  be written with a decimal point (a period or comma, followed by
        0 or more decimal digits).
 
    Default commodity
-       The  D  directive  sets a default commodity (and display format), to be
+       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
+       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
@@ -820,9 +841,9 @@
        a decimal point.
 
    Market prices
-       The P directive declares a market price,  which  is  an  exchange  rate
+       The  P  directive  declares  a  market price, which is an exchange rate
        between two commodities on a certain date.  (In Ledger, they are called
-       "historical prices".) These are often obtained from a  stock  exchange,
+       "historical  prices".)  These are often obtained from a stock exchange,
        cryptocurrency exchange, or the foreign exchange market.
 
        Here is the format:
@@ -833,97 +854,117 @@
 
        o COMMODITYA is the symbol of the commodity being priced
 
-       o COMMODITYBAMOUNT  is an amount (symbol and quantity) in a second com-
+       o COMMODITYBAMOUNT is an amount (symbol and quantity) in a second  com-
          modity, giving the price in commodity B of one unit of commodity A.
 
-       These two market price directives say that one euro was worth  1.35  US
+       These  two  market price 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
 
-       The  -V/--value flag can be used to convert reported amounts to another
+       The -V/--value flag can be used to convert reported amounts to  another
        commodity using these prices.
 
    Declaring accounts
-       account directives can be used to pre-declare  some  or  all  accounts.
-       Though not required, they can provide several benefits:
+       account  directives  can  be  used to pre-declare accounts.  Though not
+       required, they can provide several benefits:
 
        o They can document your intended chart of accounts, providing a refer-
          ence.
 
-       o They can store extra information  about  accounts  (account  numbers,
+       o They  can  store  extra  information about accounts (account numbers,
          notes, etc.)
 
-       o They  can  help  hledger know your accounts' types (asset, liability,
-         equity, revenue, expense), useful for reports like  balancesheet  and
+       o They can help hledger know your accounts'  types  (asset,  liability,
+         equity,  revenue,  expense), useful for reports like balancesheet and
          incomestatement.
 
-       o They  control  account  display order in reports, allowing non-alpha-
+       o They control account display order in  reports,  allowing  non-alpha-
          betic sorting (eg Revenues to appear above Expenses).
 
-       o They  help  with  account  name  completion  in  the   add   command,
+       o They   help   with  account  name  completion  in  the  add  command,
          hledger-iadd, hledger-web, ledger-mode etc.
 
-       Here is the full syntax:
+       The simplest form is just the word account followed by a  hledger-style
+       account name, eg:
 
-              account ACCTNAME  [ACCTTYPE]
-                [COMMENTS]
+              account assets:bank:checking
 
-       The simplest form just declares a hledger-style account name, eg:
+   Account comments
+       Comments, beginning with a semicolon, optionally including tags, can be
+       written after the account name, and/or on following lines.  Eg:
 
+              account assets:bank:checking  ; a comment
+                ; another comment
+                ; acctno:12345, a tag
+
+       Tip: comments on the same line require hledger 1.12+.  If you need your
+       journal to be compatible with older hledger versions, write comments on
+       the next line instead.
+
+   Account subdirectives
+       We also allow (and ignore) Ledger-style  indented  subdirectives,  just
+       for compatibility.:
+
               account assets:bank:checking
+                format blah blah  ; <- subdirective, ignored
 
+       Here is the full syntax of account directives:
+
+              account ACCTNAME  [ACCTTYPE] [;COMMENT]
+                [;COMMENTS]
+                [LEDGER-STYLE SUBDIRECTIVES, IGNORED]
+
    Account types
-       hledger  recognises  five  types  of account: asset, liability, equity,
-       revenue, expense.  This is useful for certain accounting-aware reports,
-       in particular balancesheet, incomestatement and cashflow.
+       hledger  recognises  five types (or classes) of account: Asset, Liabil-
+       ity, Equity, Revenue, Expense.  This is used by a few  accounting-aware
+       reports such as balancesheet, incomestatement and cashflow.
 
+   Auto-detected account types
        If you name your top-level accounts with some variation of assets, lia-
        bilities/debts, equity, revenues/income, or expenses, their  types  are
        detected automatically.
 
-       More  generally, you can declare an account's type by adding one of the
-       letters ALERX to its account directive, separated from the account name
-       by two or more spaces.  Eg:
+   Account types declared with tags
+       More  generally,  you  can  declare  an  account's type with an account
+       directive, by writing a type: tag in a comment, followed by one of  the
+       words Asset, Liability, Equity, Revenue, Expense, or one of the letters
+       ALERX (case insensitive):
 
+              account assets       ; type:Asset
+              account liabilities  ; type:Liability
+              account equity       ; type:Equity
+              account revenues     ; type:Revenue
+              account expenses     ; type:Expenses
+
+   Account types declared with account type codes
+       Or, you can write one of those letters separated from the account  name
+       by  two  or  more spaces, but this should probably be considered depre-
+       cated as of hledger 1.13:
+
               account assets       A
               account liabilities  L
               account equity       E
               account revenues     R
               account expenses     X
 
-       Note:  if  you  ever  override the types of those auto-detected english
-       account names mentioned above, you might need to  help  the  reports  a
-       bit:
+   Overriding auto-detected types
+       If you ever override the types of those auto-detected  english  account
+       names mentioned above, you might need to help the reports a bit.  Eg:
 
-              ; make "liabilities" not have the liability type, who knows why
-              account liabilities   E
+              ; make "liabilities" not have the liability type - who knows why
+              account liabilities   ; type:E
 
-              ; better ensure some other account has the liability type,
+              ; we need to ensure some other account has the liability type,
               ; otherwise balancesheet would still show "liabilities" under Liabilities
-              account -             L
-
-       )
-
-   Account comments
-       An  account  directive  can  also  have  indented comments on following
-       lines, eg:
-
-              account assets:bank:checking
-                ; acctno:12345
-                ; a comment
-
-       We also allow (and ignore) Ledger-style subdirectives, with no  leading
-       semicolon, for compatibility.
-
-       Tags  in account comments, like acctno above, currently have no effect.
+              account -             ; type:L
 
    Account display order
-       Account directives also set the order in which accounts  are  displayed
-       in  reports,  the  hledger-ui accounts screen, the hledger-web sidebar,
-       etc.  Normally accounts are listed in alphabetical order,  but  if  you
-       have eg these account directives in the journal:
+       Account  directives also set the order in which accounts are displayed,
+       eg in reports, the hledger-ui  accounts  screen,  and  the  hledger-web
+       sidebar.  By default accounts are listed in alphabetical order.  But if
+       you have these account directives in the journal:
 
               account assets
               account liabilities
@@ -931,8 +972,8 @@
               account revenues
               account expenses
 
-       you'll  see  those accounts listed in declaration order, not alphabeti-
-       cally:
+       you'll see those accounts displayed in declaration order, not alphabet-
+       ically:
 
               $ hledger accounts -1
               assets
@@ -943,16 +984,16 @@
 
        Undeclared accounts, if any, are displayed last, in alphabetical order.
 
-       Note  that  sorting  is  done at each level of the account tree (within
-       each group of sibling accounts under the same parent).  And  currently,
+       Note that sorting is done at each level of  the  account  tree  (within
+       each  group of sibling accounts under the same parent).  And currently,
        this directive:
 
               account other:zoo
 
-       would  influence the position of zoo among other's subaccounts, but not
-       the position of other among the top-level accounts.  This means: -  you
-       will  sometimes  declare  parent accounts (eg account other above) that
-       you don't intend to post to, just to customize their  display  order  -
+       would influence the position of zoo among other's subaccounts, but  not
+       the  position of other among the top-level accounts.  This means: - you
+       will sometimes declare parent accounts (eg  account other  above)  that
+       you  don't  intend  to post to, just to customize their display order -
        sibling accounts stay together (you couldn't display x:y in between a:b
        and a:c).
 
@@ -971,14 +1012,14 @@
        o customising reports
 
        Account aliases also rewrite account names in account directives.  They
-       do  not  affect  account  names  being  entered  via  hledger  add   or
+       do   not  affect  account  names  being  entered  via  hledger  add  or
        hledger-web.
 
        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
+       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
@@ -986,54 +1027,54 @@
        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  case  sensitive  full  account names.  hledger will
-       replace any occurrence of the old account name with the new one.   Sub-
+       OLD and NEW are  case  sensitive  full  account  names.   hledger  will
+       replace  any occurrence of the old account name with the new one.  Sub-
        accounts 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,
+       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-
+       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-
+       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
+       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
+       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
+       You   can  clear  (forget)  all  currently  defined  aliases  with  the
        end aliases directive:
 
               end aliases
 
    Default parent account
-       You  can  specify  a  parent  account  which  will  be prepended to all
-       accounts within a section of the journal.  Use  the  apply account  and
+       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
@@ -1050,7 +1091,7 @@
                   home:food           $10
                   home:cash          $-10
 
-       If  end apply account  is  omitted,  the effect lasts to the end of the
+       If end apply account is omitted, the effect lasts to  the  end  of  the
        file.  Included files are also affected, eg:
 
               apply account business
@@ -1059,18 +1100,18 @@
               apply account personal
               include personal.journal
 
-       Prior to hledger 1.0, legacy account and end spellings were  also  sup-
+       Prior  to  hledger 1.0, legacy account and end spellings were also sup-
        ported.
 
-       A  default parent account also affects account directives.  It does not
-       affect account names being entered via hledger add or hledger-web.   If
-       account  aliases are present, they are applied after the default parent
+       A default parent account also affects account directives.  It does  not
+       affect  account names being entered via hledger add or hledger-web.  If
+       account aliases are present, they are applied after the default  parent
        account.
 
    Periodic transactions
-       Periodic transaction rules  describe  transactions  that  recur.   They
+       Periodic  transaction  rules  describe  transactions  that recur.  They
        allow you to generate future transactions for forecasting, without hav-
-       ing to write them out explicitly  in  the  journal  (with  --forecast).
+       ing  to  write  them  out  explicitly in the journal (with --forecast).
        Secondly, they also can be used to define budget goals (with --budget).
 
        A periodic transaction rule looks like a normal journal entry, with the
@@ -1081,85 +1122,85 @@
                   expenses:rent          $2000
                   assets:bank:checking
 
-       There is an additional constraint on the period expression:  the  start
-       date   must   fall   on   a  natural  boundary  of  the  interval.   Eg
+       There  is  an additional constraint on the period expression: the start
+       date  must  fall  on  a  natural  boundary   of   the   interval.    Eg
        monthly from 2018/1/1 is valid, but monthly from 2018/1/15 is not.
 
-       Partial or relative dates (M/D, D, tomorrow, last week) in  the  period
-       expression  can work (useful or not).  They will be relative to today's
-       date, unless a Y default year directive is in  effect,  in  which  case
+       Partial  or  relative dates (M/D, D, tomorrow, last week) in the period
+       expression can work (useful or not).  They will be relative to  today's
+       date,  unless  a  Y  default year directive is in effect, in which case
        they will be relative to Y/1/1.
 
-       Period expressions must be terminated by two or more spaces if followed
-       by additional fields.  For  example,  the  periodic  transaction  given
-       below includes a transaction description "paycheck", which is separated
-       from the period expression by a double space.  If not  for  the  second
-       space,  hledger  would attempt (and fail) to parse "paycheck" as a part
-       of the period expression.
+   Two spaces after the period expression
+       If the period expression is  followed  by  a  transaction  description,
+       these must be separated by two or more spaces.  This helps hledger know
+       where the period expression ends, so that descriptions can not acciden-
+       tally alter their meaning, as in this example:
 
-              ;                                2 or more spaces
-              ;                                      ||
-              ;                                      vv
-              ~ every 2 weeks from 2018/6/4 to 2018/9  paycheck
+              ; 2 or more spaces needed here, so the period is not understood as "every 2 months in 2020"
+              ;               ||
+              ;               vv
+              ~ every 2 months  in 2020, we will review
                   assets:bank:checking   $1500
                   income:acme inc
 
    Forecasting with periodic transactions
-       With the --forecast flag,  each  periodic  transaction  rule  generates
+       With  the  --forecast  flag,  each  periodic transaction rule generates
        future transactions recurring at the specified interval.  These are not
-       saved in the journal, but appear in all reports.  They will  look  like
-       normal  transactions, but with an extra tag named recur, whose value is
+       saved  in  the journal, but appear in all reports.  They will look like
+       normal transactions, but with an extra tag named recur, whose value  is
        the generating period expression.
 
-       Forecast transactions start on the first occurrence,  and  end  on  the
-       last  occurrence,  of  their  interval within the forecast period.  The
+       Forecast  transactions  start  on  the first occurrence, and end on the
+       last occurrence, of their interval within  the  forecast  period.   The
        forecast period:
 
        o begins on the later of
 
          o the report start date if specified with -b/-p/date:
 
-         o the day after the latest normal (non-periodic) transaction  in  the
+         o the  day  after the latest normal (non-periodic) transaction in the
            journal, or today if there are no normal transactions.
 
-       o ends  on  the  report  end date if specified with -e/-p/date:, or 180
+       o ends on the report end date if specified  with  -e/-p/date:,  or  180
          days from today.
 
-       where "today" means the current date at report time.   The  "later  of"
-       rule  ensures that forecast transactions do not overlap normal transac-
+       where  "today"  means  the current date at report time.  The "later of"
+       rule ensures that forecast transactions do not overlap normal  transac-
        tions in time; they will begin only after normal transactions end.
 
-       Forecasting can be useful for estimating balances into the future,  and
-       experimenting  with  different  scenarios.   Note  the start date logic
+       Forecasting  can be useful for estimating balances into the future, and
+       experimenting with different scenarios.   Note  the  start  date  logic
        means that forecasted transactions are automatically replaced by normal
        transactions as you add those.
 
        Forecasting can also help with data entry: describe most of your trans-
-       actions with periodic rules, and every so  often  copy  the  output  of
+       actions  with  periodic  rules,  and  every so often copy the output of
        print --forecast to the journal.
 
        You can generate one-time transactions too: just write a period expres-
-       sion specifying a date with no report interval.  (You could also  write
-       a  normal  transaction  with  a future date, but remember this disables
+       sion  specifying a date with no report interval.  (You could also write
+       a normal transaction with a future date,  but  remember  this  disables
        forecast transactions on previous dates.)
 
    Budgeting with periodic transactions
-       With the --budget flag, currently supported  by  the  balance  command,
-       each  periodic transaction rule declares recurring budget goals for the
-       specified accounts.  Eg the first example  above  declares  a  goal  of
-       spending  $2000  on  rent  (and  also,  a goal of depositing $2000 into
-       checking) every month.  Goals and actual performance can then  be  com-
+       With  the  --budget  flag,  currently supported by the balance command,
+       each periodic transaction rule declares recurring budget goals for  the
+       specified  accounts.   Eg  the  first  example above declares a goal of
+       spending $2000 on rent (and also,  a  goal  of  depositing  $2000  into
+       checking)  every  month.  Goals and actual performance can then be com-
        pared in budget reports.
 
-       For  more  details, see: balance: Budget report and Cookbook: Budgeting
+       For more details, see: balance: Budget report and  Cookbook:  Budgeting
        and Forecasting.
 
 
-   Transaction Modifiers
-       Transaction modifier rules describe  changes  that  should  be  applied
-       automatically  to  certain  transactions.  Currently, this means adding
-       extra postings (also known as "automated postings").  Transaction modi-
-       fiers are enabled by the --auto flag.
+   Transaction modifiers
+       Transaction  modifier  rules  describe  changes  that should be applied
+       automatically to certain transactions.  They can be  enabled  by  using
+       the  --auto  flag.   Currently,  just  one  kind of change is possible:
+       adding extra postings.  These  rule-generated  postings  are  known  as
+       "automated postings" or "auto postings".
 
        A  transaction  modifier  rule  looks  quite like a normal transaction,
        except the first line is an  equals  sign  followed  by  a  query  that
@@ -1171,7 +1212,7 @@
                   ACCT  [AMT]
                   ...
 
-       The posting rules look just like normal postings, except the amount can
+       These posting rules look like normal postings, except  the  amount  can
        be:
 
        o a  normal  amount  with a commodity symbol, eg $2.  This will be used
@@ -1219,10 +1260,20 @@
                   assets:checking:gifts     -$20
                   assets:checking            $20
 
-       Postings added by transaction modifiers participate in transaction bal-
-       ancing, missing amount inference and balance assertions,  like  regular
-       postings.
+   Auto postings and transaction balancing / inferred amounts / balance
+       assertions
 
+       Currently, transaction modifiers are applied / auto postings are added:
+
+       o after missing amounts are inferred, and transactions are checked  for
+         balancedness,
+
+       o but before balance assertions are checked.
+
+       Note  this  means that journal entries must be balanced both before and
+       after auto postings are added.  This changed in hledger 1.12+; see #893
+       for background.
+
 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-
@@ -1240,6 +1291,7 @@
        Sublime Text   https://github.com/ledger/ledger/wiki/Edit-
                       ing-Ledger-files-with-Sublime-Text-or-RubyMine
        Textmate       https://github.com/ledger/ledger/wiki/Using-TextMate-2
+
        Text   Wran-   https://github.com/ledger/ledger/wiki/Edit-
        gler           ing-Ledger-files-with-TextWrangler
        Visual  Stu-   https://marketplace.visualstudio.com/items?item-
@@ -1270,4 +1322,4 @@
 
 
 
-hledger 1.12                     December 2018              hledger_journal(5)
+hledger 1.13                     February 2019              hledger_journal(5)
diff --git a/hledger_timeclock.5 b/hledger_timeclock.5
--- a/hledger_timeclock.5
+++ b/hledger_timeclock.5
@@ -1,5 +1,5 @@
 
-.TH "hledger_timeclock" "5" "December 2018" "hledger 1.12" "hledger User Manuals"
+.TH "hledger_timeclock" "5" "February 2019" "hledger 1.13" "hledger User Manuals"
 
 
 
@@ -9,7 +9,7 @@
 .SH DESCRIPTION
 .PP
 hledger can read timeclock files.
-As with Ledger, these are (a subset of) timeclock.el's format,
+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].
@@ -67,8 +67,8 @@
 .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.
+These rely on a "timeclock" executable which I think is just the ledger
+2 executable renamed.
 
 
 .SH "REPORTING BUGS"
diff --git a/hledger_timeclock.info b/hledger_timeclock.info
--- a/hledger_timeclock.info
+++ b/hledger_timeclock.info
@@ -4,7 +4,7 @@
 
 File: hledger_timeclock.info,  Node: Top,  Up: (dir)
 
-hledger_timeclock(5) hledger 1.12
+hledger_timeclock(5) hledger 1.13
 *********************************
 
 hledger can read timeclock files.  As with Ledger, these are (a subset
diff --git a/hledger_timeclock.txt b/hledger_timeclock.txt
--- a/hledger_timeclock.txt
+++ b/hledger_timeclock.txt
@@ -77,4 +77,4 @@
 
 
 
-hledger 1.12                     December 2018            hledger_timeclock(5)
+hledger 1.13                     February 2019            hledger_timeclock(5)
diff --git a/hledger_timedot.5 b/hledger_timedot.5
--- a/hledger_timedot.5
+++ b/hledger_timedot.5
@@ -1,11 +1,11 @@
 
-.TH "hledger_timedot" "5" "December 2018" "hledger 1.12" "hledger User Manuals"
+.TH "hledger_timedot" "5" "February 2019" "hledger 1.13" "hledger User Manuals"
 
 
 
 .SH NAME
 .PP
-Timedot \- hledger's human\-friendly time logging format
+Timedot \- hledger\[aq]s human\-friendly time logging format
 .SH DESCRIPTION
 .PP
 Timedot is a plain text format for logging dated, categorised quantities
@@ -16,10 +16,10 @@
 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.
+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.
@@ -34,7 +34,7 @@
 .IP \[bu] 2
 a sequence of dots (.) representing quarter hours.
 Spaces may optionally be used for grouping and readability.
-Eg: \&....
+Eg: ....
 \&..
 .IP \[bu] 2
 an integral or decimal number, representing hours.
diff --git a/hledger_timedot.info b/hledger_timedot.info
--- a/hledger_timedot.info
+++ b/hledger_timedot.info
@@ -4,7 +4,7 @@
 
 File: hledger_timedot.info,  Node: Top,  Next: FILE FORMAT,  Up: (dir)
 
-hledger_timedot(5) hledger 1.12
+hledger_timedot(5) hledger 1.13
 *******************************
 
 Timedot is a plain text format for logging dated, categorised quantities
diff --git a/hledger_timedot.txt b/hledger_timedot.txt
--- a/hledger_timedot.txt
+++ b/hledger_timedot.txt
@@ -124,4 +124,4 @@
 
 
 
-hledger 1.12                     December 2018              hledger_timedot(5)
+hledger 1.13                     February 2019              hledger_timedot(5)
