summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--.travis.yml113
-rw-r--r--CMakeLists.txt16
-rw-r--r--CONTRIBUTING.md8
-rw-r--r--README.md25
-rwxr-xr-xacprep20
-rw-r--r--contrib/ParseCcStmt.cs2
-rw-r--r--default.nix9
-rw-r--r--doc/CMakeLists.txt70
-rw-r--r--doc/DEVELOP.md4
-rw-r--r--doc/DEVELOP.md.new0
-rw-r--r--doc/Doxyfile.in2
-rw-r--r--doc/GLOSSARY.md2
-rw-r--r--doc/INSTALL234
-rw-r--r--doc/LICENSE2
-rw-r--r--doc/LICENSE.rtfbin1718 -> 1719 bytes
-rw-r--r--doc/NEWS33
-rw-r--r--doc/ledger-mode.texi202
-rw-r--r--doc/ledger.12
-rw-r--r--doc/ledger3.texi456
-rw-r--r--lisp/CMakeLists.txt3
-rw-r--r--lisp/ledger-commodities.el25
-rw-r--r--lisp/ledger-complete.el6
-rw-r--r--lisp/ledger-context.el6
-rw-r--r--lisp/ledger-exec.el5
-rw-r--r--lisp/ledger-fontify.el199
-rw-r--r--lisp/ledger-fonts.el188
-rw-r--r--lisp/ledger-init.el8
-rw-r--r--lisp/ledger-mode.el105
-rw-r--r--lisp/ledger-navigate.el168
-rw-r--r--lisp/ledger-occur.el157
-rw-r--r--lisp/ledger-post.el130
-rw-r--r--lisp/ledger-reconcile.el162
-rw-r--r--lisp/ledger-regex.el36
-rw-r--r--lisp/ledger-report.el76
-rw-r--r--lisp/ledger-schedule.el260
-rw-r--r--lisp/ledger-sort.el33
-rw-r--r--lisp/ledger-state.el14
-rw-r--r--lisp/ledger-test.el14
-rw-r--r--lisp/ledger-texi.el2
-rw-r--r--lisp/ledger-xact.el43
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/account.cc2
-rw-r--r--src/account.h6
-rw-r--r--src/amount.cc2
-rw-r--r--src/amount.h6
-rw-r--r--src/annotate.cc2
-rw-r--r--src/annotate.h2
-rw-r--r--src/archive.cc2
-rw-r--r--src/archive.h2
-rw-r--r--src/balance.cc2
-rw-r--r--src/balance.h2
-rw-r--r--src/chain.cc2
-rw-r--r--src/chain.h2
-rw-r--r--src/commodity.cc2
-rw-r--r--src/commodity.h2
-rw-r--r--src/compare.cc2
-rw-r--r--src/compare.h2
-rw-r--r--src/context.h2
-rw-r--r--src/convert.cc2
-rw-r--r--src/convert.h2
-rw-r--r--src/csv.cc2
-rw-r--r--src/csv.h2
-rw-r--r--src/draft.cc2
-rw-r--r--src/draft.h2
-rw-r--r--src/emacs.cc2
-rw-r--r--src/emacs.h2
-rw-r--r--src/error.cc2
-rw-r--r--src/error.h2
-rw-r--r--src/expr.cc2
-rw-r--r--src/expr.h2
-rw-r--r--src/exprbase.h2
-rw-r--r--src/filters.cc4
-rw-r--r--src/filters.h2
-rw-r--r--src/flags.h2
-rw-r--r--src/format.cc2
-rw-r--r--src/format.h2
-rw-r--r--src/generate.cc2
-rw-r--r--src/generate.h2
-rw-r--r--src/global.cc6
-rw-r--r--src/global.h8
-rw-r--r--src/history.cc2
-rw-r--r--src/history.h2
-rw-r--r--src/item.cc2
-rw-r--r--src/item.h6
-rw-r--r--src/iterators.cc2
-rw-r--r--src/iterators.h2
-rw-r--r--src/journal.cc2
-rw-r--r--src/journal.h2
-rw-r--r--src/lookup.cc2
-rw-r--r--src/lookup.h2
-rw-r--r--src/main.cc2
-rw-r--r--src/mask.cc2
-rw-r--r--src/mask.h2
-rw-r--r--src/op.cc2
-rw-r--r--src/op.h2
-rw-r--r--src/option.cc2
-rw-r--r--src/option.h2
-rw-r--r--src/org.cc2
-rw-r--r--src/org.h2
-rw-r--r--src/output.cc2
-rw-r--r--src/output.h2
-rw-r--r--src/parser.cc2
-rw-r--r--src/parser.h2
-rw-r--r--src/pool.cc2
-rw-r--r--src/pool.h2
-rw-r--r--src/post.cc2
-rw-r--r--src/post.h6
-rw-r--r--src/precmd.cc2
-rw-r--r--src/precmd.h2
-rw-r--r--src/predicate.h2
-rw-r--r--src/print.cc2
-rw-r--r--src/print.h2
-rw-r--r--src/pstream.h6
-rw-r--r--src/ptree.cc7
-rw-r--r--src/ptree.h2
-rw-r--r--src/py_account.cc29
-rw-r--r--src/py_amount.cc2
-rw-r--r--src/py_balance.cc10
-rw-r--r--src/py_commodity.cc2
-rw-r--r--src/py_expr.cc2
-rw-r--r--src/py_format.cc2
-rw-r--r--src/py_item.cc2
-rw-r--r--src/py_journal.cc2
-rw-r--r--src/py_post.cc2
-rw-r--r--src/py_session.cc4
-rw-r--r--src/py_times.cc2
-rw-r--r--src/py_utils.cc2
-rw-r--r--src/py_value.cc2
-rw-r--r--src/py_xact.cc2
-rw-r--r--src/pyfstream.h2
-rw-r--r--src/pyinterp.cc2
-rw-r--r--src/pyinterp.h2
-rw-r--r--src/pyledger.cc2
-rw-r--r--src/pyutils.h2
-rw-r--r--src/query.cc2
-rw-r--r--src/query.h2
-rw-r--r--src/quotes.cc2
-rw-r--r--src/quotes.h2
-rw-r--r--src/report.cc9
-rw-r--r--src/report.h6
-rw-r--r--src/scope.cc2
-rw-r--r--src/scope.h2
-rw-r--r--src/select.cc9
-rw-r--r--src/select.h2
-rw-r--r--src/session.cc7
-rw-r--r--src/session.h4
-rw-r--r--src/stats.cc2
-rw-r--r--src/stats.h2
-rw-r--r--src/stream.cc2
-rw-r--r--src/stream.h2
-rw-r--r--src/system.hh.in7
-rw-r--r--src/temps.cc2
-rw-r--r--src/temps.h2
-rw-r--r--src/textual.cc43
-rw-r--r--src/timelog.cc2
-rw-r--r--src/timelog.h2
-rw-r--r--src/times.cc6
-rw-r--r--src/times.h6
-rw-r--r--src/token.cc2
-rw-r--r--src/token.h2
-rw-r--r--src/unistring.h2
-rw-r--r--src/utils.cc4
-rw-r--r--src/utils.h4
-rw-r--r--src/value.cc2
-rw-r--r--src/value.h2
-rw-r--r--src/views.cc2
-rw-r--r--src/views.h2
-rw-r--r--src/xact.cc4
-rw-r--r--src/xact.h2
-rw-r--r--test/CMakeLists.txt31
-rwxr-xr-xtest/DocTests.py22
-rw-r--r--test/baseline/opt-primary-date.test99
-rw-r--r--test/baseline/opt-trace.test15
-rwxr-xr-xtest/convert.py2
-rw-r--r--test/regress/1038_1.test18
-rw-r--r--test/regress/1038_2.test18
-rw-r--r--test/regress/1038_3.test20
-rw-r--r--test/regress/1072.test31
-rw-r--r--test/regress/1074.test161
-rw-r--r--test/regress/5D92A5EB.test2
-rw-r--r--test/regress/730.test37
-rw-r--r--test/regress/A013A73B.test10
-rwxr-xr-xtools/prepare-commit-msg27
-rwxr-xr-xtools/travis-before_install.sh17
-rwxr-xr-xtools/travis-install.sh23
186 files changed, 2451 insertions, 1345 deletions
diff --git a/.gitignore b/.gitignore
index a558cf67..16ee2784 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,11 +1,13 @@
*.[oa]
*.so
*.so.*
+*.dylib
*.backup
*.elc
*.gcov
*.l[oa]
*.pyc
+*.sw[p-z]
*~
.timestamp
*.tar.bz2
diff --git a/.travis.yml b/.travis.yml
index b4999235..5f026e6c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,44 +1,103 @@
# Since the Travis CI environment http://docs.travis-ci.com/user/ci-environment/
-# provides GNU GCC 4.6, which does not support -std=c++11 GNU GCC 4.8 is
-# installed. Additionally boost 1.55.0 is compiled from source, since in the
-# Travis CI environment only boost 1.46 is available and no backported package
-# was found on the net.
+# provides GNU GCC 4.6, which does not support -std=c++11 GNU GCC 4.8 is installed
+
+# NOTE: Please validate this file after editing it using
+# Travis WebLint http://lint.travis-ci.org/
+# or travis-yaml https://github.com/travis-ci/travis-yaml
language: cpp
compiler:
- - clang
- gcc
+ - clang
+os:
+ - linux
+ - osx
+sudo: false
+cache:
+ apt: true
+
+env:
+ global:
+ # Boost version to use:
+ # _MIN is used when building the master branch
+ # _MAX is used when building any other branch
+ - BOOST_VERSION_MIN="1.49.0"
+ - BOOST_VERSION_MAX="1.58.0"
+ # List of required boost libraries to build
+ - BOOST_LIBS="date_time,filesystem,iostreams,python,regex,system,test"
+ # List of required Homebrew formulae to install
+ - BREWS="gmp,mpfr"
+
+matrix:
+ exclude:
+ - os: linux
+ compiler: clang
+ # Compiling ledger on Linux with clang
+ # either crashes clang or results in a ledger binary that crashes with SIGSEGV.
+ - os: osx
+ compiler: gcc
+ # On Mac OS X building ledger with GNU GCC 4.8 fails due to
+ # undefined symbols, maybe because boost was not being built with g++-4.8.
+ # Undefined symbols for architecture x86_64:
+ # "boost::re_detail::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::construct_init(boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags)", referenced from:
+ # boost::re_detail::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::perl_matcher(char const*, char const*, boost::match_results<char const*, std::allocator<boost::sub_match<char const*> > >&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags, char const*) in main.cc.o
+ # boost::re_detail::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::perl_matcher(char const*, char const*, boost::match_results<char const*, std::allocator<boost::sub_match<char const*> > >&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags, char const*) in global.cc.o
+ # "boost::re_detail::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::find()", referenced from:
+ # bool boost::regex_search<char const*, char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >(char const*, char const*, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags) in main.cc.o
+ # bool boost::regex_search<char const*, char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >(char const*, char const*, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags) in global.cc.o
+
+addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ #- boost-latest
+ packages:
+ - gcc-4.8
+ - g++-4.8
+ - libgmp-dev
+ - libmpfr-dev
+ - libedit-dev
+ #- libboost1.55-dev
+ #- libboost-test1.55-dev
+ #- libboost-regex1.55-dev
+ #- libboost-python1.55-dev
+ #- libboost-system1.55-dev
+ #- libboost-date-time1.55-dev
+ #- libboost-iostreams1.55-dev
+ #- libboost-filesystem1.55-dev
+ #- libboost-serialization1.55-dev
before_install:
- # Add software package repository, containing updated build toochain, i.e. GNU GCC 4.8
- - sudo add-apt-repository ppa:ubuntu-toolchain-r/test --yes
- - sudo apt-get update -qq
- # Download boost 1.55 and extract the source archive
- - wget --no-verbose --output-document=boost-trunk.tar.bz2 http://sourceforge.net/projects/boost/files/boost/1.55.0/boost_1_55_0.tar.bz2/download
- - export BOOST_ROOT="$TRAVIS_BUILD_DIR/../boost-trunk"
- - export CMAKE_MODULE_PATH="$BOOST_ROOT"
- - mkdir -p $BOOST_ROOT
- - tar jxf boost-trunk.tar.bz2 --strip-components=1 -C $BOOST_ROOT
-
-install:
- # Install GNU GCC 4.8 required by use of C++11
- - sudo apt-get install -qq g++-4.8 gcc-4.8
- - export CXX="g++-4.8" CC="gcc-4.8"
- # Build boost libraries required by ledger
- - (cd $BOOST_ROOT; ./bootstrap.sh --with-libraries=date_time,filesystem,system,iostreams,regex,python,test)
- - (cd $BOOST_ROOT; ./b2 threading=multi --prefix=$BOOST_ROOT -d0 install)
- # Install further dependencies
- - ./acprep dependencies
+ - if [ "${TRAVIS_BRANCH}" = "master" ]; then export BOOST_VERSION="${BOOST_VERSION_MIN}"; else export BOOST_VERSION="${BOOST_VERSION_MAX}"; fi
+ - if [ -n "${BOOST_VERSION}" ]; then export BOOST_ROOT="${TRAVIS_BUILD_DIR}/../boost-trunk"; export CMAKE_MODULE_PATH="${BOOST_ROOT}"; fi
+ - if [ "${CXX}" = "g++" ]; then export CXX="$(which g++-4.8)"; export CC="$(which gcc-4.8)"; fi
+ - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then export DYLD_LIBRARY_PATH="${BOOST_ROOT}/lib"; fi
+ # c++ is a symlink to clang++, but the compiler behaves differently when invoked as c++
+ - if [ "${TRAVIS_OS_NAME}" = "osx" -a "${CXX}" = "clang++" ]; then export CXX="$(which c++)"; export CC="$(which cc)"; fi
+ - tools/travis-before_install.sh
+
+install:
+ - tools/travis-install.sh
before_script:
- - ./acprep opt make --python --boost=$BOOST_ROOT
+ - cmake . -DUSE_PYTHON=ON -DBUILD_DEBUG=ON
+ - make
script:
- - ./acprep check -- --output-on-failure
+ - make test
- PYTHONPATH=. python python/demo.py
+after_script:
+ # These scripts are run for informational purposes and
+ # should be reintegrated into CTest once they reliably verify the documentation.
+ - python test/CheckTexinfo.py -l ledger -s .
+ - python test/CheckManpage.py -l ledger -s .
+
notifications:
email:
on_success: change
on_failure: change
- irc: "chat.freenode.net#ledger"
+ irc:
+ channels: [ "chat.freenode.net#ledger" ]
+ on_success: change
+ on_failure: change
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8a5fc850..ca82084e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,15 +1,22 @@
cmake_minimum_required(VERSION 2.8.5)
+if(POLICY CMP0042)
+ # CMP0042 is only known to CMake 3.0 and above
+ cmake_policy(SET CMP0042 OLD)
+endif(POLICY CMP0042)
PROJECT(ledger)
set(Ledger_VERSION_MAJOR 3)
-set(Ledger_VERSION_MINOR 0)
-set(Ledger_VERSION_PATCH 3)
-set(Ledger_VERSION_DATE 20140608)
+set(Ledger_VERSION_MINOR 1)
+set(Ledger_VERSION_PATCH 0)
+set(Ledger_VERSION_DATE 20141005)
enable_testing()
add_definitions(-std=c++11)
+if (CYGWIN)
+ add_definitions(-U__STRICT_ANSI__)
+endif()
########################################################################
@@ -45,6 +52,7 @@ endif()
########################################################################
+set(Python_ADDITIONAL_VERSIONS 2.7 2.6)
find_package(PythonInterp) # Used for running tests
if (USE_PYTHON)
@@ -52,7 +60,6 @@ if (USE_PYTHON)
message(ERROR "Building the python module requires BUILD_LIBRARY=ON.")
endif()
- set(Python_ADDITIONAL_VERSIONS 2.7 2.6)
find_package(PythonLibs)
if (PYTHONLIBS_FOUND)
set(BOOST_PYTHON python)
@@ -87,6 +94,7 @@ check_function_exists(access HAVE_ACCESS)
check_function_exists(realpath HAVE_REALPATH)
check_function_exists(getpwuid HAVE_GETPWUID)
check_function_exists(getpwnam HAVE_GETPWNAM)
+check_function_exists(ioctl HAVE_IOCTL)
check_function_exists(isatty HAVE_ISATTY)
check_c_source_compiles("
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..a4b8b14f
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,8 @@
+Tips for contributors
+---------------------
+
+* Please **make pull requests against `next`, not `master`**.
+ Ledger follows a [git-flow](http://nvie.com/posts/a-successful-git-branching-model/) branching model,
+ in which development happens on the `next` branch and is subsequently merged into `master` for releases.
+* If you're making **changes to `ledger-mode`, or other files for which the Travis build is not
+ relevant**, please **add `[ci skip]` to the end of the commit message**.
diff --git a/README.md b/README.md
index 09e809c8..e18792d6 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[![Build Status](https://travis-ci.org/ledger/ledger.png?branch=master)](https://travis-ci.org/ledger/ledger)
+[![Build Status](https://travis-ci.org/ledger/ledger.svg?branch=master)](https://travis-ci.org/ledger/ledger)
# Ledger: Command-Line Accounting
@@ -48,7 +48,7 @@ major bugs that you find. Just e-mail me, or post to the mailing list,
they'll become a part of my work list.
<table>
-<tr><td><strong>RELEASE</strong></td><td><tt>git checkout v2.6.3</tt></td></tr>
+<tr><td><strong>RELEASE</strong></td><td><tt>git checkout v3.1</tt></td></tr>
<tr><td><strong>CURRENT</strong></td><td><tt>git checkout maint</tt></td></tr>
<tr><td><strong>BETA</strong></td><td><tt>git checkout -b master origin/master</tt></td></tr>
<tr><td><strong>ALPHA</strong></td><td><tt>git checkout -b next origin/next</tt></td></tr>
@@ -96,7 +96,26 @@ And for building the current `maint` branch:
<tr><td>libxml2</td><td>2.7.2</td><td><em>optional</em></td></tr>
</table>
-### MacPorts
+### OS X
+
+You can use [MacPorts](https://www.macports.org/) or [homebrew](http://brew.sh/) to install this very quickly on OS X.
+
+#### 1. Homebrew
+
+You can see the parameters you can pass while installing with brew by the command `brew options ledger`. To install ledger, simply type the following command:
+
+ brew install ledger
+
+If everything worked well, you should have ledger working now. If you want to install this with python bindings, you can use the following command:
+
+ brew install ledger --with-python
+
+If you to want to startup python, use the following command:
+
+ ledger python
+
+
+#### 2. MacPorts
If you build stuff using MacPorts on OS X, as I do, here is what you would
run:
diff --git a/acprep b/acprep
index 7984f767..9e661aad 100755
--- a/acprep
+++ b/acprep
@@ -1,10 +1,7 @@
#!/usr/bin/env python
-# acprep, version 3.0
+# acprep, version 3.1
#
-# This script configures my ledger source tree on my Mac OS/X machine. This
-# is not necessary, however, since I keep all the files necessary for building
-# checked in to the source tree. Users can just type './configure && make'.
# This script simply sets up the compiler and linker flags for all the various
# build permutations I use for testing and profiling.
@@ -647,6 +644,9 @@ class PrepareBuild(CommandLineApp):
]
self.log.info('Executing: ' + ' '.join(packages))
self.execute(*packages)
+ elif system.startswith('CYGWIN'):
+ self.log.info('Looks like you are using Cygwin')
+ self.log.info('Please install the dependencies manually.')
#########################################################################
# Determine the system's basic configuration #
@@ -685,7 +685,10 @@ class PrepareBuild(CommandLineApp):
if self.options.python:
self.configure_args.append('-DUSE_PYTHON=1')
- if self.options.use_ninja:
+ if system.startswith('CYGWIN'):
+ self.configure_args.append('-G')
+ self.configure_args.append('Unix Makefiles')
+ elif self.options.use_ninja:
self.configure_args.append('-GNinja')
if exists('/Users/johnw/Projects/ledger/plan/TODO'):
@@ -802,7 +805,7 @@ class PrepareBuild(CommandLineApp):
conf_args.append('-DCMAKE_CXX_FLAGS=%s' %
self.envvars[var])
elif var == 'LDFLAGS':
- conf_args.append('-DCMAKE_EXE_LINKER_FLAGS=%s' %
+ conf_args.append('-DCMAKE_EXE_LINKER_FLAGS=%s' %
self.envvars[var])
if self.options.boost_root:
@@ -815,9 +818,6 @@ class PrepareBuild(CommandLineApp):
if self.options.boost_include:
conf_args.append('-DBOOST_INCLUDEDIR=%s' %
self.options.boost_include)
- if self.options.build_dir:
- conf_args.append('-DBUILD_DIR=%s' %
- self.options.build_dir)
if self.prefix_directory():
conf_args.append('-DCMAKE_INSTALL_PREFIX=%s' % self.prefix_directory())
@@ -898,7 +898,7 @@ class PrepareBuild(CommandLineApp):
self.log.debug('Changing directory to ' + build_dir)
os.chdir(build_dir)
- self.execute(*(['ninja' if self.options.use_ninja else 'make'] +
+ self.execute(*(['ninja' if self.options.use_ninja else 'make'] +
make_args))
finally:
os.chdir(self.source_dir)
diff --git a/contrib/ParseCcStmt.cs b/contrib/ParseCcStmt.cs
index c9ad1d55..04e3dbb9 100644
--- a/contrib/ParseCcStmt.cs
+++ b/contrib/ParseCcStmt.cs
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2008, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/default.nix b/default.nix
index 1b0bd1dc..30da83ec 100644
--- a/default.nix
+++ b/default.nix
@@ -2,13 +2,12 @@
, texinfo, gnused }:
let
- rev = "20140507";
+ rev = "20141005";
in
stdenv.mkDerivation {
- name = "ledger-3.0.3.${rev}";
-
- src = ./.;
+ name = "ledger-3.1.0.${rev}";
+ src = builtins.filterSource (path: type: type != "unknown") ./.;
buildInputs = [ cmake boost gmp mpfr libedit python texinfo gnused ];
@@ -18,7 +17,7 @@ stdenv.mkDerivation {
# broken in ledger...
postInstall = ''
mkdir -p $out/share/emacs/site-lisp/
- cp -v $src/lisp/*.el $out/share/emacs/site-lisp/
+ cp -v "$src/lisp/"*.el $out/share/emacs/site-lisp/
'';
meta = {
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 9bf1bffe..46c3f73f 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -27,27 +27,34 @@ endif()
########################################################################
-if (NOT BUILD_DOCS)
- add_custom_target(doc DEPENDS doc.doxygen)
- return()
+# BUILD_WEB_DOCS implies BUILD_DOCS
+if (BUILD_WEB_DOCS)
+ set(BUILD_DOCS 1)
endif()
-set(info_files ledger3.texi ledger-mode.texi)
+if (BUILD_DOCS)
+ find_program(MAKEINFO makeinfo)
+ find_program(TEXI2PDF texi2pdf)
+ find_program(TEX tex)
+ find_program(MAN2HTML man2html)
+ find_program(GROFF groff)
+ set(ledger_info_files ledger3.texi ledger-mode.texi)
+
+ if (NOT MAKEINFO)
+ message(WARNING "Could not find makeinfo. Info version of documentation cannot be built.")
+ endif()
-find_program(MAKEINFO makeinfo)
-find_program(TEXI2PDF texi2pdf)
-find_program(TEX tex)
-find_program(MAN2HTML man2html)
-find_program(GROFF groff)
+ if (NOT TEXI2PDF OR NOT TEX)
+ message(WARNING "Could not find texi2pdf or tex. PDF version of documentation will not be built.")
+ endif()
+endif()
########################################################################
-foreach(file ${info_files})
+foreach(file ${ledger_info_files})
get_filename_component(file_base ${file} NAME_WE)
- if (NOT MAKEINFO)
- message(WARNING "Could not find makeinfo. Info version of documentation cannot be built.")
- else()
+ if (MAKEINFO)
add_custom_command(OUTPUT ${file_base}.info
COMMAND makeinfo --force --no-split -o ${file_base}.info ${CMAKE_CURRENT_SOURCE_DIR}/${file}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${file}
@@ -55,20 +62,15 @@ foreach(file ${info_files})
list(APPEND ledger_doc_files ${file_base}.info)
endif()
- if (BUILD_WEB_DOCS)
- if (NOT MAKEINFO)
- message(WARNING "Could not find makeinfo. HTML version of documentation cannot be built.")
- endif()
+ if (BUILD_WEB_DOCS AND MAKEINFO)
add_custom_command(OUTPUT ${file_base}.html
COMMAND makeinfo --force --html --no-split -o ${file_base}.html ${CMAKE_CURRENT_SOURCE_DIR}/${file}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${file}
VERBATIM)
list(APPEND ledger_doc_files ${file_base}.html)
- endif(BUILD_WEB_DOCS)
+ endif()
- if (NOT TEXI2PDF OR NOT TEX)
- message(WARNING "Could not find texi2pdf or tex. PDF version of documentation will not be built.")
- else()
+ if (TEXI2PDF AND TEX)
if (BUILD_A4_PDF)
set(papersize --texinfo=@afourpaper)
endif()
@@ -117,22 +119,16 @@ if (CMAKE_INSTALL_MANDIR)
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 COMPONENT doc)
endif(CMAKE_INSTALL_MANDIR)
-foreach(file ${info_files})
- get_filename_component(file_base ${file} NAME_WE)
+foreach(file ${ledger_doc_files})
+ get_filename_component(file_ext ${file} EXT)
- if (CMAKE_SOURCE_DIR STREQUAL BUILD_DIR)
- set(doc_dir ${CMAKE_CURRENT_SOURCE_DIR})
- else()
- get_filename_component(dir_base ${CMAKE_CURRENT_SOURCE_DIR} NAME_WE)
- set(doc_dir "${CMAKE_SOURCE_DIR}/${BUILD_DIR}/${dir_base}")
- endif()
-
- install(FILES ${doc_dir}/${file_base}.info
- DESTINATION ${CMAKE_INSTALL_INFODIR} COMPONENT doc)
- install(FILES ${doc_dir}/${file_base}.pdf
- DESTINATION ${CMAKE_INSTALL_DOCDIR} COMPONENT doc OPTIONAL)
- if (BUILD_WEB_DOCS)
- install(FILES ${doc_dir}/${file_base}.html
+ if(file_ext STREQUAL ".info")
+ if(CMAKE_INSTALL_INFODIR)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${file}
+ DESTINATION ${CMAKE_INSTALL_INFODIR} COMPONENT doc)
+ endif()
+ elseif(CMAKE_INSTALL_DOCDIR)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${file}
DESTINATION ${CMAKE_INSTALL_DOCDIR} COMPONENT doc)
- endif(BUILD_WEB_DOCS)
+ endif()
endforeach()
diff --git a/doc/DEVELOP.md b/doc/DEVELOP.md
index e3a479d7..ce897741 100644
--- a/doc/DEVELOP.md
+++ b/doc/DEVELOP.md
@@ -14,7 +14,7 @@ used by *./python/server.py*.
from source code. It uses the *CMakeLists.txt* files.
[**DOxygen**](http://doxygen.org): generates programming documentation from
-source code files. Primarly used on C++ sources, but works on all. Uses
+source code files. Primarily used on C++ sources, but works on all. Uses
the *doc/Doxyfile.in* file.
[**GCC**](http://gcc.gnu.org): Gnu Compiler Collection, which includes the
@@ -58,7 +58,7 @@ orientation:
for more information.
**./README.md**: user readme file in markdown format, also used as the project
- discription on GitHub.
+ description on GitHub.
**./contrib/**: contributed scripts of random quality and completion. They
usually require editing to run.
diff --git a/doc/DEVELOP.md.new b/doc/DEVELOP.md.new
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/doc/DEVELOP.md.new
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
index e340d84a..95373660 100644
--- a/doc/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -938,7 +938,7 @@ HTML_STYLESHEET =
# user-defined cascading style sheet that is included after the standard
# style sheets created by doxygen. Using this option one can overrule
# certain style aspects. This is preferred over using HTML_STYLESHEET
-# since it does not replace the standard style sheet and is therefor more
+# since it does not replace the standard style sheet and is therefore more
# robust against future updates. Doxygen will copy the style sheet file to
# the output directory.
diff --git a/doc/GLOSSARY.md b/doc/GLOSSARY.md
index 507958c1..263a3cff 100644
--- a/doc/GLOSSARY.md
+++ b/doc/GLOSSARY.md
@@ -33,7 +33,7 @@ ACCOUNTING GLOSSARY
This data of where money goes can be collated into reports. This used to be
done with a physical book, called a ledger, where each account was on one
page. Each debit or credit in the journal was transferred to the
- appropriate account page and the pages were totalled to produce reports.
+ appropriate account page and the pages were totaled to produce reports.
This process is now done with the Ledger software which creates reports from
the journal. A journal is sometimes called a register.
diff --git a/doc/INSTALL b/doc/INSTALL
deleted file mode 100644
index 5458714e..00000000
--- a/doc/INSTALL
+++ /dev/null
@@ -1,234 +0,0 @@
-Installation Instructions
-*************************
-
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006 Free Software Foundation, Inc.
-
-This file is free documentation; the Free Software Foundation gives
-unlimited permission to copy, distribute and modify it.
-
-Basic Installation
-==================
-
-Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package. The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package.
-
- The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
- It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring. Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
-
- If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release. If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
- The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'. You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
-
-The simplest way to compile this package is:
-
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system.
-
- Running `configure' might take a while. While running, it prints
- some messages telling which features it is checking for.
-
- 2. Type `make' to compile the package.
-
- 3. Optionally, type `make check' to run any self-tests that come with
- the package.
-
- 4. Type `make install' to install the programs and any data files and
- documentation.
-
- 5. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
-Compilers and Options
-=====================
-
-Some systems require unusual options for compilation or linking that the
-`configure' script does not know about. Run `./configure --help' for
-details on some of the pertinent environment variables.
-
- You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment. Here
-is an example:
-
- ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
- *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
-You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory. To do this, you can use GNU `make'. `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.
-
- With a non-GNU `make', it is safer to compile the package for one
-architecture at a time in the source code directory. After you have
-installed the package for one architecture, use `make distclean' before
-reconfiguring for another architecture.
-
-Installation Names
-==================
-
-By default, `make install' installs the package's commands under
-`/usr/local/bin', include files under `/usr/local/include', etc. You
-can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX'.
-
- You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. If you
-pass the option `--exec-prefix=PREFIX' to `configure', the package uses
-PREFIX as the prefix for installing programs and libraries.
-Documentation and other data files still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
-options like `--bindir=DIR' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.
-
- If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-Optional Features
-=================
-
-Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
- For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-Specifying the System Type
-==========================
-
-There may be some features `configure' cannot figure out automatically,
-but needs to determine by the type of machine the package will run on.
-Usually, assuming the package is built to be run on the _same_
-architectures, `configure' can figure that out, but if it prints a
-message saying it cannot guess the machine type, give it the
-`--build=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
- CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
- OS KERNEL-OS
-
- See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
- If you are _building_ compiler tools for cross-compiling, you should
-use the option `--target=TYPE' to select the type of system they will
-produce code for.
-
- If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
-If you want to set default values for `configure' scripts to share, you
-can create a site shell script called `config.site' that gives default
-values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
-Variables not defined in a site shell script can be set in the
-environment passed to `configure'. However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost. In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'. For example:
-
- ./configure CC=/usr/local2/bin/gcc
-
-causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf bug. Until the bug is fixed you can use this workaround:
-
- CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
-
-`configure' Invocation
-======================
-
-`configure' recognizes the following options to control how it operates.
-
-`--help'
-`-h'
- Print a summary of the options to `configure', and exit.
-
-`--version'
-`-V'
- Print the version of Autoconf used to generate the `configure'
- script, and exit.
-
-`--cache-file=FILE'
- Enable the cache: use and save the results of the tests in FILE,
- traditionally `config.cache'. FILE defaults to `/dev/null' to
- disable caching.
-
-`--config-cache'
-`-C'
- Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
- Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
- messages will still be shown).
-
-`--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
-
-`configure' also accepts some other, not widely useful, options. Run
-`configure --help' for more details.
-
diff --git a/doc/LICENSE b/doc/LICENSE
index df1a0028..92be3a1d 100644
--- a/doc/LICENSE
+++ b/doc/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2009, John Wiegley. All rights reserved.
+Copyright (c) 2003-2015, John Wiegley. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
diff --git a/doc/LICENSE.rtf b/doc/LICENSE.rtf
index 8da96b65..471065fe 100644
--- a/doc/LICENSE.rtf
+++ b/doc/LICENSE.rtf
Binary files differ
diff --git a/doc/NEWS b/doc/NEWS
index 1a433228..45596ddc 100644
--- a/doc/NEWS
+++ b/doc/NEWS
@@ -1,12 +1,21 @@
Ledger NEWS
-* 3.x
+* 3.1
+
+- Changed the definition of cost basis to preserve the original cost basis
+ when a gain or loss is made (if you bought 1 AAA for $10 and then sold
+ it for $12, ledger would previously take $12 as the cost; the original
+ cost of $10 is preserved as the cost basis now, which addresses strange
+ behavior with -B after a capital gain or loss is made).
+
+- Incorrect automatic Equity:Capital Gains and Equity:Capital Loss entries
+ are no longer generated when a commodity is sold for loss or profit.
- Support for virtual posting costs.
- The option --permissive now quiets balance assertions
-- Remove SHA1 files due to license issues and use boost instead.
+- Removed SHA1 files due to license issues and use boost instead.
- Added option --no-pager to disable the pager.
@@ -14,8 +23,24 @@
- Added option --recursive-aliases to expand aliases recursively
+- Support payee "uuid" directive.
+
+- Bug fix: when a status flag (! or *) is explicitly specified for an
+ individual posting, it always has a priority over entire transaction
+ status.
+
+- Bug fix: don't lose commodity when cost is not separated by whitespace
+
+- Improved backwards compatibility with ledger 2.x
+
- Build fix for GCC 4.9
+- Build fix for boost 1.56
+
+- Many improvements to ledger-mode, including fontification
+
+- More test cases and unit tests
+
- Contrib: Added script to generate commodities from ISO 4217
* 3.0
@@ -314,7 +339,7 @@ features, please see the manual.
This flag limits computation to *only transactions whose amount
is greater than 100 of a given commodity*. It means that if you
scan your dining expenses, for example, only individual bills
- greater than $100 would be caculated by the report.
+ greater than $100 would be calculated by the report.
--only "a>100"
@@ -556,7 +581,7 @@ features, please see the manual.
* 2.4.1
-- Corrected an issue that had inadvertantly disabled Gnucash support.
+- Corrected an issue that had inadvertently disabled Gnucash support.
* 2.4
diff --git a/doc/ledger-mode.texi b/doc/ledger-mode.texi
index c8af96cb..b76cb309 100644
--- a/doc/ledger-mode.texi
+++ b/doc/ledger-mode.texi
@@ -119,9 +119,9 @@ initialization file (@file{~/.emacs}, @file{~/.emacs.d/init.el}, or
@file{~/.Aquamacs/Preferences.el}).
@lisp
+(autoload 'ledger-mode "ledger-mode" "A major mode for Ledger" t)
(add-to-list 'load-path
(expand-file-name "/path/to/ledger/source/lisp/"))
-(load "ledger-mode")
(add-to-list 'auto-mode-alist '("\\.ledger$" . ledger-mode))
@end lisp
@@ -175,6 +175,13 @@ typing a close match to the payee. Ledger-mode will call @command{ledger
xact} with the data you enter and place the transaction in the proper
chronological place in the ledger.
+If you need to add a lot of transactions that are not near your current
+date you can set the current year and month so that using @samp{Add
+Transaction} will prompt you with a more convenient month and year. To
+set the month type @kbd{C-c RET} and enter the month you want. @kbd{C-c
+C-y} will prompt you for the year. These settings only effect the
+@samp{Add Transaction} command.
+
@node Reconciliation, Reports, Quick Add, Quick Demo
@subsection Reconciliation
@kindex C-c C-r
@@ -218,10 +225,10 @@ Emacs will prompt for a report name. There are a few built-in reports,
and you can add any report you need @xref{Adding and Editing Reports}.
In the Minibuffer type @samp{account}. When prompted for an account
-type @samp{checking}. In another buffer you will see a Ledger register
-report. You can move around the buffer, with the point on a transaction,
-type @kbd{C-c C-c}. Ledger-mode will take you directly to that
-transaction in the @file{demo.ledger} buffer.
+type @samp{checking}. In a buffer named @file{*Ledger Report*}, you
+will see a Ledger register report. You can move around the buffer, with
+the point on a transaction, type @kbd{RET}. Ledger-mode will take you
+directly to that transaction in the @file{demo.ledger} buffer.
Another built-in report is the balance report. In the
@file{demo.ledger} buffer, type @kbd{C-c C-o C-r}. When prompted for
@@ -231,13 +238,15 @@ will be shown.
@node Narrowing, , Reports, Quick Demo
@subsection Narrowing
@kindex C-c C-f
+@kindex C-c C-g
A ledger file can get very large. It can be helpful to collapse the
buffer to display only the transactions you are interested in.
Ledger-mode copies the @command{occur} mode functionality. Typing
@kbd{C-c C-f} and entering any regex in the Minibuffer will show only
transactions that match the regex. The regex can be on any field, or
-amount.
+amount. Use @kbd{C-c C-g} after editing transactions to re-apply the
+current regex. Cancel the narrowing by typing @kbd{C-c C-f} again.
@node The Ledger Buffer, The Reconcile Buffer, Introduction to Ledger-mode, Top
@chapter The Ledger Buffer
@@ -247,17 +256,12 @@ amount.
* Copying Transactions::
* Editing Amounts::
* Marking Transactions::
+* Formatting Transactions::
* Deleting Transactions::
* Sorting Transactions::
* Narrowing Transactions::
@end menu
-@c TODO
-@c Describe also:
-@c - Align Region
-@c - Set effective date C-c C-t
-@c - Set Year C-c C-t
-@c - Set Month C-c RET
@node Adding Transactions, Copying Transactions, The Ledger Buffer, The Ledger Buffer
@section Adding Transactions
@@ -273,17 +277,35 @@ payees and accounts. Included files are not currently included in the
completion scan. Repeatedly hitting @kbd{TAB} will cycle through the
possible completions.
-Ledger-mode can also help you keep your amounts in alignment. Setting
+Ledger-mode can also help you keep your amounts aligned. Setting
@option{ledger-post-auto-adjust-amounts} to true tells Ledger-mode to
automatically place any amounts such that their last digit is aligned to
the column specified by @option{ledger-post-amount-alignment-column},
which defaults to @samp{52}. @xref{Ledger Post Customization Group}.
@menu
+* Setting a Transactions Effective Date::
* Quick Balance Display::
@end menu
-@node Quick Balance Display, , Adding Transactions, Adding Transactions
+@node Setting a Transactions Effective Date, Quick Balance Display, Adding Transactions, Adding Transactions
+@subsection Setting a Transactions Effective Date
+@kindex C-c C-t
+@cindex effective date
+
+Ledger provides for adding information to a transaction that add details
+to the dates. For example, you can specify when the transaction was
+entered, when the transaction was cleared, or when individual postings
+were cleared.
+Ledger-mode refers to these additional dates as @emph{effective} dates.
+To set the effective date of a transaction, place the point in the first
+line of a transaction and type @kbd{C-c C-t}. The effective date will
+be added to the transaction. To set the effective date for an
+individual posting, place point in the posting and type @kbd{C-c C-t} and
+the effective date for that posting will be added at the end of the
+posting.
+
+@node Quick Balance Display, , Setting a Transactions Effective Date, Adding Transactions
@subsection Quick Balance Display
@kindex C-c C-p
@cindex balance
@@ -327,7 +349,7 @@ but it cannot intercept the value being yanked form the @command{Calc}
stack, so decimal-comma users will have to manually replace the period
with a comma.
-@node Marking Transactions, Deleting Transactions, Editing Amounts, The Ledger Buffer
+@node Marking Transactions, Formatting Transactions, Editing Amounts, The Ledger Buffer
@section Marking Transactions
@cindex transaction, marking
@cindex uncleared
@@ -369,7 +391,20 @@ point in a transaction. This places an asterisk @samp{*} after the
date. Clearing individual postings is done by typing @kbd{C-c C-c}
while in a posting. This places an asterisk prior to the posting.
-@node Deleting Transactions, Sorting Transactions, Marking Transactions, The Ledger Buffer
+@node Formatting Transactions, Deleting Transactions, Marking Transactions, The Ledger Buffer
+@section Formatting Transactions
+@cindex transaction, formatting
+
+When editing a transaction, liberal use of the @kbd{TAB} key can keep
+the transaction well formatted. If you want to have Ledger-mode cleanup
+the formatting of a transaction you can use @samp{Align Transaction} or
+@samp{Align Region} from the menu bar.
+
+The menu item @samp{Clean-up Buffer} sorts all transactions in the buffer
+by date, removes extraneous empty lines and aligns every transaction.
+
+
+@node Deleting Transactions, Sorting Transactions, Formatting Transactions, The Ledger Buffer
@section Deleting Transactions
@kindex C-c C-d
@cindex transaction, deleting
@@ -421,6 +456,7 @@ automatically delete old markers and put new new marker at point.
@node Narrowing Transactions, , Sorting Transactions, The Ledger Buffer
@section Narrowing Transactions
@kindex C-c C-f
+@kindex C-c C-g
@cindex transaction, narrowing
@cindex transaction, display filtering
@@ -436,12 +472,11 @@ The regular expression can match on any part of the transaction. If you
want to find all transactions whose amount ends in @samp{.37}, you can
do that (I don't know why, but hey, whatever ever floats you aerostat).
-Using @kbd{C-c C-f} or the @samp{Narrow to Regex} menu entry, enter
-a regular expression in the Minibuffer. Ledger-mode will hide all other
-transactions. For details of the regular expression syntax, see
-@ref{(emacs)Regexps, Syntax of Regular Expressions} or
-@ref{(elisp)Regular Expressions, Regular Expressions}. A few examples
-using the @file{demo.ledger} are given here:
+Using @kbd{C-c C-f} or the @samp{Narrow to Regex} menu entry, enter a
+regular expression in the Minibuffer. Ledger-mode will hide all other
+transactions. For details of the regular expression syntax, see your
+Emacs documentation. A few examples using the @file{demo.ledger} are
+given here:
@table @samp
@@ -467,6 +502,10 @@ Show only transactions with any line ending with @samp{harley}.
To show back all transactions simply invoke @samp{Narrow to Regex} or
@kbd{C-c C-f} again.
+If you've edited some transactions after narrowing such that they would
+no longer match the regular expression, you can refresh the narrowed
+view using @kbd{C-c C-g}.
+
@node The Reconcile Buffer, The Report Buffer, The Ledger Buffer, Top
@chapter The Reconcile Buffer
@@ -602,22 +641,18 @@ type @kbd{t} and enter the new target value.
* Reversing Report Order::
@end menu
-@c TODO Describe also:
-@c - Goto Report C-c C-o C-g
-@c - Re-run Report C-c C-o C-a
-@c - Save Report C-c C-o C-s
-@c - Kill Report C-c C-o C-k
-
@node Running Basic Reports, Adding and Editing Reports, The Report Buffer, The Report Buffer
@section Running Reports
@kindex C-c C-o C-r
+@kindex C-c C-o C-g
+@kindex C-c C-o C-a
@cindex report, running
The real power behind Ledger is in its amazing reporting capability.
Ledger-mode provides easy facility to run reports directly from Emacs.
It has four reports built-in and facilities for adding custom reports.
-Typing @kbd{C-c C-o C-r} or using menu @samp{Ledger Run Report} prompt
+Typing @kbd{C-c C-o C-r} or using menu @samp{Run Report} prompts
for the name of a saved report. The built-in reports are:
@table @var
@@ -638,6 +673,18 @@ transactions involving that account.
@end table
+While viewing reports you can easily switch back and forth between the
+ledger buffer and the @file{*Ledger Report*} buffer. In @file{*Ledger
+Report*} buffer, typing @kbd{RET} will take you to that transaction in
+the ledger buffer. While in the ledger buffer @kbd{C-c C-o C-g} returns
+you to the @file{*Ledger Report*} buffer.
+
+By default Ledger-mode will refresh the report buffer when the ledger
+buffer is saved. If you want to rerun the report at another time
+@kbd{C-c C-o C-a}. This is useful if you have other programs altering
+your ledger file outside of Emacs.
+
+
@node Adding and Editing Reports, Reversing Report Order, Running Basic Reports, The Report Buffer
@section Adding and Editing Reports
@findex ledger-reports
@@ -667,18 +714,21 @@ buffer you will have the option to give it a new name, or overwrite the
old report.
Deleting reports is accomplished by typing @kbd{C-c C-o C-e} or using
-@samp{Edit Reports} menu in the ledger buffer, or typing @kbd{e} in the
+@samp{Edit Report} menu in the ledger buffer, or typing @kbd{e} in the
@file{*Ledger Report*} buffer. This takes you to the Emacs
customization window for the Ledger Reports variables. Use the widgets
to delete the report you want removed.
+Typing @kbd{C-c C-o C-s} will prompt for a name and save the current
+report.
+
@node Expansion Formats, Make Report Transactions Active, Adding and Editing Reports, Adding and Editing Reports
@subsection Expansion Formats
@cindex report, custom variable
It is sometimes convenient to leave room to customize a report without
saving the command line every time. For example running a register
-report for a specific account, enter at runtime by the user. The
+report for a specific account entered at runtime by the user. The
built-in report @var{account} does exactly that, using a variable
expansion to prompt the user for the account to use. There are four
variables that can be expanded to run a report:
@@ -694,9 +744,11 @@ Prompts for a payee.
@item account
Prompt for an account.
-@c FIXME : is it 'value' or 'tag' for '@item value' just below?
-@item value
-Prompt for a tag value.
+@item tagname
+Prompt for a meta-data tag name.
+
+@item tagvalue
+Prompt for a meta-data tag value.
@end table
@@ -742,14 +794,14 @@ maintain the proper mathematical sense.
@node Scheduling Transactions, Customizing Ledger-mode, The Report Buffer, Top
@chapter Scheduling Transactions
-The Ledger program provide for automating transactions but these
+The Ledger program provides for automating transactions but these
transaction aren't ``real'', they only exist inside a ledger session and
are not reflected in the actual data file. Many transactions are very
repetitive, but may vary slightly in the date they occur on, or the
amount. Some transactions are weekly, monthly, quarterly or annually.
Ledger mode provides a way to schedule upcoming transaction with a
flexible scheduler that allows you to specify the transactions in a
-separate ledger file and calculate the upcoming occurences of those
+separate ledger file and calculate the upcoming occurrences of those
transactions. You can then copy the transactions into your live data
file.
@@ -757,13 +809,66 @@ file.
* Specifying Upcoming Transactions::
@end menu
-@node Specifying Upcoming Transactions
+@node Specifying Upcoming Transactions, , Scheduling Transactions, Scheduling Transactions
@section Specifying Upcoming Transactions
The format for specifying transactions is identical to Ledger's file
format with the exception of the date field. The data field is modified
-by surrounding it with brackets and using wild cards to specity free
-months or years.
+by surrounding it with brackets and using wild cards and special
+characters to specify when the transactions should appear.
+
+@menu
+* Transactions that occur on specific dates::
+* Transactions that occur on specific days::
+@end menu
+
+@node Transactions that occur on specific dates, Transactions that occur on specific days, Specifying Upcoming Transactions, Specifying Upcoming Transactions
+@subsection Transactions that occur on specific dates
+
+Many times you will enter repetitive transactions that occur on the same
+day of the month each month. These can be specified using a wild card
+in the year and month with a fixed date in the day. The following entry
+specifies a transaction that occurs on the first and fifteenth of every
+month in every year.
+@example
+[*/*/1,15] Paycheck
+ Income:Job $1000.00
+ Assets:Checking
+@end example
+
+Some transactions do not occur every month. Comma separated lists of
+the months, or @samp{E} for even, or @samp{O} for odd number months can
+also be specified. The following entry specifies a bi-monthly
+exterminator bill that occurs in the even months:
+@example
+[*/E/01] Exterminator
+ Expenses:Home $100.00
+ Assets:Checking
+@end example
+
+@node Transactions that occur on specific days, , Transactions that occur on specific dates, Specifying Upcoming Transactions
+@subsection Transactions that occur on specific days
+
+Some transactions occur every relative to the day of the week rather
+than the date of the month. For example, many people are paid every two
+weeks without regard to the day of the month. Other events may occur on
+specific days regardless of the date. For example the following
+transactions creates a transaction every other Thursday:
+
+@example
+[2014/11/27+2Th] Paycheck
+ Income:Job $1000.00
+ Assets:Checking
+@end example
+
+It is necessary to specify a starting date in order for this type of
+recurrence relation to be specified. The day names are two character
+codes that default to Mo, Tu, We, Th, Fr, Sa, Su, for Monday, Tuesday,
+Wednesday, Thursday, Friday, Saturday, Sunday respectively. You can
+change the codes to something more convenient for your locale by
+customizing the ledger @var{ledger-schedule-week-days}. They must be two
+characters long.
+
@node Customizing Ledger-mode, Generating Ledger Regression Tests, Scheduling Transactions, Top
@@ -837,11 +942,11 @@ the reconcile regex.
@item ledger-buffer-tracks-reconcile-buffer
If non-nil, then when the cursor is moved to a new transaction in the
-reconcile window.
+@file{*Reconcile*} window.
@item ledger-reconcile-force-window-bottom
-If non-nil, make the reconcile window appear along the bottom of the
-register window and resize.
+If non-nil, make the @file{*Reconcile*} window appear along the bottom
+of the register window and resize.
@item ledger-reconcile-toggle-to-pending
If non-nil, then toggle between uncleared and pending @samp{!}. If
@@ -909,13 +1014,15 @@ Default face for Ledger occur mode shown transactions.
Face for Ledger comments.
@item ledger-font-reconciler-uncleared-face
-Default face for uncleared transactions in the reconcile window.
+Default face for uncleared transactions in the @file{*Reconcile*} buffer.
@item ledger-font-reconciler-cleared-face
-Default face for cleared @samp{*} transactions in the reconcile window.
+Default face for cleared @samp{*} transactions in the @file{*Reconcile*}
+buffer.
@item ledger-font-reconciler-pending-face
-Default face for pending @samp{!} transactions in the reconcile window.
+Default face for pending @samp{!} transactions in the @file{*Reconcile*}
+buffer.
@item ledger-font-report-clickable-face
FIXME
@@ -1024,3 +1131,8 @@ Work in Progress.
@printindex ky
@bye
+
+@c Local Variables:
+@c mode: texinfo
+@c TeX-master: t
+@c End:
diff --git a/doc/ledger.1 b/doc/ledger.1
index cde81248..b4746eb9 100644
--- a/doc/ledger.1
+++ b/doc/ledger.1
@@ -439,7 +439,7 @@ statement will print balances only for account with
two levels, i.e.
.Nm Expenses:Entertainment
but not
-.Nm Expenses:entertainemnt:Dining .
+.Nm Expenses:entertainment:Dining .
This is a display predicate, which
means it only affects display, not the total calculations.
.It Fl \-deviation Pq Fl D
diff --git a/doc/ledger3.texi b/doc/ledger3.texi
index c7613c0e..62869a29 100644
--- a/doc/ledger3.texi
+++ b/doc/ledger3.texi
@@ -14,7 +14,7 @@
@c | @var | | Ledger CLI option Variable (like -f FILE) |
@c | | | Ledger file Syntax |
@c | @samp | | Valued example or single char |
-@c | @file | | File |
+@c | @file | | File, Buffer |
@c | @file | | Program (like ledger, report, acprep) |
@c Restructuring manual ideas
@@ -22,53 +22,53 @@
@c How to make documented ledger examples validate automatically.
@c
-@c The test/DocTests.py script will be run along the with the other
-@c tests when using ctest or acprep check.
+@c The test/DocTests.py script will be run along with the other tests
+@c when using ctest or acprep check.
@c The script parses the texinfo file and looks for three kinds of
@c specially marked @smallexamples, then it will run the ledger
-@c command from the exmaple, and compare the results with the output
+@c command from the example, and compare the results with the output
@c from the documentation.
@c
@c To specially mark a @smallexample append @c command:UUID, where
@c UUID is the first 7 digits from the commands sha1sum, e.g.:
-@c
+@c
@c @smallexample @c command:CDE330A
@c $ ledger -f sample.dat reg expenses
@c @end smallexample
-@c
+@c
@c Then DocTests.py will look for corresponding documented output,
@c which may appear anywhere in the file, and is marked with
@c @smallexample @c output:UUID where UUID is the UUID from the
@c corresponding ledger command example, e.g.:
-@c
+@c
@c @smallexample @c output:CDE330A
@c 04-May-27 Book Store Expenses:Books $20.00 $20.00
@c Expenses:Cards $40.00 $60.00
@c Expenses:Docs $30.00 $90.0
@c @end smallexample
-@c
+@c
@c Now where does this data in sample.dat come from?
@c DocTests.py is a bit smart about ledger's file argument, since
@c it will check if the given filename exists in the test/input/
@c directory.
-@c
+@c
@c Sometimes the journal data for an example is specified within
@c the documentation itself, in that case the journal example data
@c needs to be specially marked as well using @smallexample @c input:UUID,
@c again with the UUID being the UUID of the corresponding ledger example
@c command. If multiple inputs with the same UUID are found they will be
@c concatenated together and given as one set of data to the example command.
-@c
+@c
@c @smallexample @c input:35CB2A3
@c 2014/02/09 The Italian Place
@c Expenses:Food:Dining $ 36.84
@c Assets:Cash
@c @end smallexample
-@c
+@c
@c @smallexample @c command:35CB2A3
@c $ ledger -f inline.dat accounts
@c @end smallexample
-@c
+@c
@c @smallexample @c output:35CB2A3
@c Assets:Cash
@c Expenses:Food:Dining
@@ -86,17 +86,16 @@
@c $ 36.84 Expenses:Food:Dining
@c @end smallexample
@c
-@c Additionally DocTests.py will pass --init-file /dev/null to ledger to
-@c ignore any default arguments to ledger the user running the tests
-@c has configured.
-@c
+@c Additionally DocTests.py will pass --args-only and --columns 80 to ledger
+@c to ignore any default arguments from the environment or .ledgerrc.
+@c
@c To manually run the tests in this file run:
@c $ ./test/DocTests.py -vv --ledger ./ledger --file ./doc/ledger3.texi
-
+
@copying
-Copyright @copyright{} 2003–2014, John Wiegley. All rights reserved.
+Copyright @copyright{} 2003–2015, John Wiegley. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -147,7 +146,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@titlepage
@title Ledger: Command-Line Accounting
-@subtitle For Version 3.0 of Ledger
+@subtitle For Version 3.1 of Ledger
@author John Wiegley
@page
@vskip 0pt plus 1filll
@@ -1756,7 +1755,7 @@ both liquid and commodity assets. Now, on the day of the sale:
@smallexample @c input:validate
2005/08/01 Stock sale
- Assets:Broker -50 APPL @{$30.00@} @@ $50.00
+ Assets:Broker -50 AAPL @{$30.00@} @@ $50.00
Expenses:Broker:Commissions $19.95
Income:Capital Gains $-1,000.00
Assets:Broker $2,480.05
@@ -1858,7 +1857,7 @@ A valuation function receives three arguments:
@table @code
-@item source
+@item source
A string identifying the commodity whose price is being asked for
(example: @samp{EUR}).
@@ -1995,8 +1994,8 @@ freeform text editor to enter transactions makes it easy to keep the
data, but also easy to enter accounts or payees inconsistently or with
spelling errors.
-In order to combat inconsistency you can define allowable accounts and
-payees. For simplicity, create a separate text file and define accounts
+In order to combat inconsistency you can define allowable accounts and
+payees. For simplicity, create a separate text file and define accounts
and payees like
@smallexample
@@ -2023,7 +2022,8 @@ $ ledger accounts >> Accounts.dat
@end smallexample
@noindent
-You will have to edit this file to add the @code{account} directive in front of every line.
+You will have to edit this file to add the @code{account} directive in
+front of every line.
@node Journal Format, Converting from other formats, Keeping it Consistent, Keeping a Journal
@section Journal Format
@@ -2148,8 +2148,8 @@ account Expenses:Food
@end smallexample
The @code{note} sub-directive associates a textual note with the
-account. This can be accessed later using the @code{note} value expression
-function in any account context.
+account. This can be accessed later using the @code{note} value
+expression function in any account context.
The @code{alias} sub-directive, which can occur multiple times, allows
the alias to be used in place of the full account name anywhere that
@@ -2226,9 +2226,9 @@ $ ledger bal --no-total ^Exp
$10.00 Expenses:Entertainment:Dining
@end smallexample
-With the option @option{--recursive-aliases}, aliases can refer to other aliases,
-the following example produces exactly the same transactions and account names
-as the preceding one:
+With the option @option{--recursive-aliases}, aliases can refer to other
+aliases, the following example produces exactly the same transactions
+and account names as the preceding one:
@smallexample @c input:validate
alias Entertainment=Expenses:Entertainment
@@ -2248,7 +2248,7 @@ $ ledger balance --no-total --recursive-aliases ^Exp
$10.00 Expenses:Entertainment:Dining
@end smallexample
-The option @option{--no-aliases} completely disables alias expansion.
+The option @option{--no-aliases} completely disables alias expansion.
All accounts are read verbatim as they are in the ledger file.
@item assert
@@ -2268,7 +2268,7 @@ balance to zero. Ledger allows you to leave one posting with no
amount and automatically balance the transaction in the
posting. The @code{bucket} allows you to fill in all postings and
automatically generate an additional posting to the bucket account
-balancing the transaction. If any transaction is unbalanced, it
+balancing the transaction. If any transaction is unbalanced, it
will automatically be balanced against the @code{bucket} account.
The following example sets @samp{Assets:Checking} as the bucket:
@@ -2316,8 +2316,8 @@ check <VALUE EXPRESSION BOOLEAN RESULT>
Start a block comment, closed by @code{end comment}.
@item commodity
-Pre-declare commodity names. This only has an effect if @option{--strict}
-or @option{--pedantic} is used (see below).
+Pre-declare commodity names. This only has an effect if
+@option{--strict} or @option{--pedantic} is used (see below).
@smallexample @c input:validate
commodity $
@@ -2325,7 +2325,7 @@ commodity CAD
@end smallexample
The @code{commodity} directive supports several optional
-sub-directives, if they immediately follow the commodity directive
+sub-directives, if they immediately follow the commodity directive
and---if they are on successive lines---begin with whitespace:
@smallexample @c input:validate
@@ -2344,8 +2344,8 @@ format this commodity. In the future, using this directive will disable
Ledger's observation of other ways that commodity is used, and will
provide the ``canonical'' representation.
-The @code{nomarket} sub-directive states that the commodity's price should
-never be auto-downloaded.
+The @code{nomarket} sub-directive states that the commodity's price
+should never be auto-downloaded.
The @code{default} sub-directive marks this as the ``default'' commodity.
@@ -2388,7 +2388,7 @@ fixed CAD $0.90
2012-04-11 Second day Dinner in Canada
Assets:Wallet -25.75 CAD
Expenses:Food 25.75 CAD
-endfixed
+endfixed CAD
@end smallexample
is equivalent to this:
@@ -2517,8 +2517,8 @@ tag CSV
@end smallexample
The @code{tag} directive supports two optional sub-directives, if they
-immediately follow the tag directive and---if on a successive line---begin
-with whitespace:
+immediately follow the tag directive and---if on a successive
+line---begin with whitespace:
@smallexample @c input:validate
tag Receipt
@@ -2529,8 +2529,8 @@ tag Receipt
The @code{check} and @code{assert} sub-directives warn or error
(respectively) if the given value expression evaluates to false within
the context of any use of the related tag. In such a context,
-``value'' is bound to the value of the tag (which may be something else
-but a string if typed metadata is used!). Such checks or assertions are
+``value'' is bound to the value of the tag (which may be something else
+but a string if typed metadata is used!). Such checks or assertions are
not called if no value is given.
@item test
@@ -2815,9 +2815,9 @@ you a place to put those codes:
@findex --uncleared
@findex --pending
-A transaction can have a ``state'': cleared, pending, or uncleared.
-The default is uncleared. To mark a transaction cleared, put an asterisk (*)
-before the payee, after the date or code:
+A transaction can have a ``state'': cleared, pending, or uncleared. The
+default is uncleared. To mark a transaction cleared, put an asterisk
+@samp{*} before the payee, after the date or code:
@smallexample @c input:validate
2012-03-10 * KFC
@@ -2975,9 +2975,10 @@ used as the payee name for that posting. This affects the
@command{register} report, the @command{payees} report, and the
@option{--by-payee} option.
-This is useful when for example you deposit 4 checks at a time to
-the bank. On the bank statement, there is just one amount @samp{$400},
-but you can specify from whom each check came from, as shown by example below:
+This is useful when for example you deposit 4 checks at a time to the
+bank. On the bank statement, there is just one amount @samp{$400}, but
+you can specify from whom each check came from, as shown by example
+below:
@smallexample @c input:validate
2010-06-17 Sample
@@ -3138,8 +3139,8 @@ A balance assignment has this form:
Assets:Cash = $500.00
@end smallexample
-This sets the amount of the second posting to whatever it would need
-to be for the total in @samp{Assets:Cash} to be $500.00 after the posting.
+This sets the amount of the second posting to whatever it would need to
+be for the total in @samp{Assets:Cash} to be $500.00 after the posting.
If the resulting amount is not $-20.00 in this case, it is an error.
@node Resetting a balance, Balancing transactions, Balance assignments, Balance verification
@@ -3174,9 +3175,9 @@ As a consequence of all the above, consider the following transaction:
@end smallexample
What this says is: set the amount of the posting to whatever value is
-needed so that @samp{Assets:Brokerage} contains 10 AAPL. Then, because this
-posting must balance, ensure that its value is zero. This can only be
-true if Assets:Brokerage does indeed contain 10 AAPL at that point in
+needed so that @samp{Assets:Brokerage} contains 10 AAPL. Then, because
+this posting must balance, ensure that its value is zero. This can only
+be true if Assets:Brokerage does indeed contain 10 AAPL at that point in
the input file.
A balanced virtual transaction is used simply to indicate to Ledger that
@@ -3246,9 +3247,10 @@ Said another way, whenever Ledger sees a posting cost of the form
"AMOUNT @@ AMOUNT", the commodity used in the second amount is marked
``primary''.
-The only meaning a primary commodity has is that the @option{--market (-V)}
-flag will never convert a primary commodity into any other commodity.
-@option{--exchange @var{COMMODITY} (-X)} still will, however.
+The only meaning a primary commodity has is that the @option{--market
+(-V)} flag will never convert a primary commodity into any other
+commodity. @option{--exchange @var{COMMODITY} (-X)} still will,
+however.
@node Posting cost expressions, Total posting costs, Explicit posting costs, Transactions
@section Posting cost expressions
@@ -3325,10 +3327,10 @@ For example, consider the stock sale given above:
@end smallexample
The commodity transferred into @samp{Assets:Brokerage} is not actually 10
-AAPL, but rather 10 AAPL @{$5.00@}. The figure in braces after the
+AAPL, but rather 10 AAPL @{$50.00@}. The figure in braces after the
amount is called the ``lot price''. It's Ledger's way of remembering
that this commodity was transferred through an exchange, and that
-$5.00 was the price of that exchange.
+$50.00 was the price of that exchange.
This becomes significant if you later sell that commodity again. For
example, you might write this:
@@ -3386,12 +3388,12 @@ but is not required to be used with them:
@end smallexample
It should be noted that this is a convenience only for cases where you
-buy and sell whole lots. The @{@{$500.00@}@} is @emph{not} an
-attribute of the commodity, whereas @{$5.00@} is. In fact, when you write
+buy and sell whole lots. The @{@{$500.00@}@} is @emph{not} an attribute
+of the commodity, whereas @{$5.00@} is. In fact, when you write
@{@{$500.00@}@}, Ledger just divides that value by 10 and sees
@{$50.00@}. So if you use the print command to look at this
-transaction, you'll see the single braces form in the output.
-The double braces price form is a shorthand only.
+transaction, you'll see the single braces form in the output. The
+double braces price form is a shorthand only.
Plus, it comes with dangers. This works fine:
@@ -3522,8 +3524,8 @@ indicate a virtual cost:
Income:Capital Gains $-125.00
@end smallexample
-You can specify any combination of lot prices, dates or notes, in any order.
-They are all optional.
+You can specify any combination of lot prices, dates or notes, in any
+order. They are all optional.
To show all lot information in a report, use @option{--lots}.
@@ -3714,9 +3716,9 @@ This becomes:
@node Referring to the matching posting's account, Applying metadata to every matched posting, Accessing the matching posting's amount, Automated Transactions
@subsection Referring to the matching posting's account
-Sometimes you want to refer to the account that was matched
-in some way within the automated transaction itself. This is
-done by using the string @samp{$account}, anywhere within the
+Sometimes you want to refer to the account that was matched
+in some way within the automated transaction itself. This is
+done by using the string @samp{$account}, anywhere within the
account part of the automated posting:
@smallexample @c input:validate
@@ -3881,8 +3883,8 @@ This entry accomplishes this. Every month you'll see an
automatic $37.50 deficit like you should, while your checking account
really knows that it debited $225 this month.
-And using the @option{--effective} option, the initial date will be overridden
-by the effective dates.
+And using the @option{--effective} option, the initial date will be
+overridden by the effective dates.
@smallexample @c command:6453542
$ ledger --effective register Groceries
@@ -4401,10 +4403,11 @@ report -J -l "Ua>=@{\$0.01@}" -d "d>=[last feb]" reg ^assets ^liab
The last report uses both a calculation predicate @option{--limit
@var{EXPR} (-l)} and a display predicate @option{--display @var{EXPR}
(-d)}. The calculation predicate limits the report to postings whose
-amount is greater than or equal to $1 (which can only happen if the posting amount
-is in dollars). The display predicate limits the transactions
-@emph{displayed} to just those since last February, even though those
-transactions from before will be computed as part of the balance.
+amount is greater than or equal to $1 (which can only happen if the
+posting amount is in dollars). The display predicate limits the
+transactions @emph{displayed} to just those since last February, even
+though those transactions from before will be computed as part of the
+balance.
@node Reporting Commands, Command-line Syntax, Building Reports, Top
@chapter Reporting Commands
@@ -4449,11 +4452,11 @@ balances for an account, such as when @ref{Archiving Previous Years}.
@findex --amount-data
@findex --total-data
-The @command{register} command displays all the postings occurring
-in a single account, line by line. The account regex must be
-specified as the only argument to this command. If any regexes occur
-after the required account name, the register will contain only those
-postings that match, which makes it very useful for hunting down a particular
+The @command{register} command displays all the postings occurring in
+a single account, line by line. The account regex must be specified as
+the only argument to this command. If any regexes occur after the
+required account name, the register will contain only those postings
+that match, which makes it very useful for hunting down a particular
posting.
The output from @command{register} is very close to what a typical
@@ -4465,8 +4468,8 @@ If you have ``Gnuplot'' installed, you may plot the amount or running
total of any register by using the script @file{report}, which is
included in the Ledger distribution. The only requirement is that you
add either @option{--amount-data (-j)} or @option{--total-data (-J)} to
-your @command{register} command, in order to plot either the amount or total
-column, respectively.
+your @command{register} command, in order to plot either the amount or
+total column, respectively.
@node The @command{print} command, , The @command{register} command, Primary Financial Reports
@subsection The @command{print} command
@@ -4547,9 +4550,10 @@ Transaction Number,Date,Description,Memo,Amount Debit,Amount Credit,Balance,Chec
Unfortunately, as it stands Ledger cannot read it, but you can. Ledger
expects the first line to contain a description of the fields on each
-line of the file. The fields ledger can recognize are called
-@code{date}, @code{posted}, @code{code}, @code{payee} or @code{desc},
-@code{amount}, @code{cost}, @code{total}, and @code{note}.
+line of the file. The fields ledger can recognize contain these
+case-insensitive strings @code{date}, @code{posted}, @code{code},
+@code{payee} or @code{desc} or @code{description}, @code{amount},
+@code{cost}, @code{total}, and @code{note}.
Delete the account description lines at the top, and replace the first
line in the data above with:
@@ -4582,17 +4586,17 @@ transid,date,payee,note,amount,,,code,
@end smallexample
Ledger will include @samp{; transid: 767718} in the first transaction
-is from the file above.
+from the file above.
@findex --invert
@findex --account @var{STR}
@findex --rich-data
-The @command{convert} command accepts three options. The most important
-ones are @option{--invert} which inverts the amount field, and
+The @command{convert} command accepts three options. They are
+@option{--invert} which inverts the amount field,
@option{--account @var{STR}} which you can use to specify the account to
-balance against and @option{--rich-data}. When using the rich-data
-switch, additional metadata is stored as tags. There is, for example,
+balance against, and @option{--rich-data} which stores
+additional metadata as tags. There is, for example,
a UUID field. If an entry with the same UUID tag is already included in
the normal ledger file (specified via @option{--file @var{FILE} (-f)} or
via the environment variable @env{LEDGER_FILE}) this entry will not be
@@ -4613,7 +4617,7 @@ account Aufwand:Einkauf:Lebensmittel
Note that it may be necessary for the output of @samp{ledger convert}
to be passed through @code{ledger print} a second time if you want to
-match on the new payee field. During the @code{ledger convert} run
+match on the new payee field. During the @code{ledger convert} run,
only the original payee name as specified in the csv data seems to be
used.
@@ -5194,18 +5198,20 @@ pricedb database files.
@subsection @command{accounts}
@findex accounts
-The @command{accounts} command reports all of the accounts in the journal.
-Following the command with a regular expression will limit the output to
-accounts matching the regex. The output is sorted by name. Using the
-@option{--count} option will tell you how many entries use each account.
+The @command{accounts} command reports all of the accounts in the
+journal. Following the command with a regular expression will limit the
+output to accounts matching the regex. The output is sorted by name.
+Using the @option{--count} option will tell you how many entries use
+each account.
@node @command{payees}, @command{commodities}, @command{accounts}, Reports about your Journals
@subsection @command{payees}
@findex payees
-The @command{payees} command reports all of the unique payees in the journal.
-Using the @option{--count} option will tell you how many entries use
-each payee. To filter the payees displayed you must use the prefix @@:
+The @command{payees} command reports all of the unique payees in the
+journal. Using the @option{--count} option will tell you how many
+entries use each payee. To filter the payees displayed you must use the
+prefix @@:
@smallexample
$ ledger payees @@Nic
@@ -5228,10 +5234,10 @@ you how many entries use each commodity.
@findex tags
@findex --values
-The @command{tags} command reports all of the tags in the journal. The output
-is sorted by name. Using the @option{--count} option will tell you how
-many entries use each tag. Using the @option{--values} option will
-report the values used by each tag.
+The @command{tags} command reports all of the tags in the journal. The
+output is sorted by name. Using the @option{--count} option will tell
+you how many entries use each tag. Using the @option{--values} option
+will report the values used by each tag.
@node @command{xact}, @command{stats}, @command{tags}, Reports about your Journals
@subsection @command{xact}
@@ -5239,7 +5245,7 @@ report the values used by each tag.
@findex entry
@findex xact
-The @command{xact} command simplify the creation of new transactions.
+The @command{xact} command simplifies the creation of new transactions.
It works on the principle that 80% of all postings are variants of
earlier postings. Here's how it works:
@@ -5252,7 +5258,7 @@ Say you currently have this posting in your ledger file:
Liabilities:MasterCard $-15.00
@end smallexample
-Now it's @samp{2004/4/9}, and you've just eating at @samp{Viva Italiano}
+Now it's @samp{2004/4/9}, and you've just eaten at @samp{Viva Italiano}
again. The exact amounts are different, but the overall form is the
same. With the @command{xact} command you can type:
@@ -5358,7 +5364,7 @@ There are many, many command options available with the @file{ledger}
program, and it takes a while to master them. However, none of them are
required to use the basic reporting commands.
-@node Command Line Quick Reference, Detailed Option Description, Basic Usage, Command-line Syntax
+@node Command Line Quick Reference, Detailed Option Description, Basic Usage, Command-line Syntax
@section Command Line Quick Reference
@menu
@@ -5371,7 +5377,7 @@ required to use the basic reporting commands.
* Commodity Reporting::
@end menu
-@node Basic Reporting Commands, Basic Options, Command Line Quick Reference, Command Line Quick Reference
+@node Basic Reporting Commands, Basic Options, Command Line Quick Reference, Command Line Quick Reference
@subsection Basic Reporting Commands
@ftable @code
@@ -5405,7 +5411,8 @@ Print account balances as transactions.
Print price history for matching commodities.
@item pricedb
-Print price history for matching commodities in a format readable by ledger.
+Print price history for matching commodities in a format readable by
+ledger.
@item xact
Generate transactions based on previous postings.
@@ -5531,7 +5538,7 @@ Accounts, tags or commodities not previously declared will cause errors.
@item --check-payees
Enable strict and pedantic checking for payees as well as accounts,
-commodities and tags. This only works in conjunction with
+commodities and tags. This only works in conjunction with
@option{--strict} or @option{--pedantic}.
@item --immediate
@@ -5717,7 +5724,7 @@ Report net gain or loss for commodities that have a price history.
@end ftable
-@node Detailed Option Description, Period Expressions, Command Line Quick Reference, Command-line Syntax
+@node Detailed Option Description, Period Expressions, Command Line Quick Reference, Command-line Syntax
@section Detailed Option Description
@menu
@@ -5847,7 +5854,7 @@ a decimal separator, not the usual period.
@item --download
@itemx -Q
-Direct Ledger to download prices using the script defined via the option
+Direct Ledger to download prices using the script defined via the option
@option{--getquote @var{FILE}}.
@item --explicit
@@ -5933,9 +5940,9 @@ a misspelled commodity or account) it will issue a warning giving you
the file and line number of the problem.
@item --recursive-aliases
-Normally, ledger only expands aliases once. With this option, ledger tries
-to expand the result of alias expansion recursively, until no more expansions
-apply.
+Normally, ledger only expands aliases once. With this option, ledger
+tries to expand the result of alias expansion recursively, until no more
+expansions apply.
@item --time-colon
The @option{--time-colon} option will display the value for a seconds
@@ -6049,7 +6056,7 @@ $ ledger reg Expenses --begin Dec --bold-if "amount>100"
@end smallexample
@noindent
-list all transactions since the beginning of December and print in
+list all transactions since the beginning of December and print in
bold any posting greater than $100.
@item --budget
@@ -6141,7 +6148,7 @@ Transform the date of the transaction using @var{EXPR}.
@item --date-format @var{DATE_FORMAT}
@itemx -y @var{DATE_FORMAT}
-Specify the format ledger should use to read and print dates
+Specify the format ledger should use to read and print dates
(@pxref{Date and Time Format Codes}).
@item --date-width @var{INT}
@@ -6154,7 +6161,7 @@ FIX THIS ENTRY @c ASK JOHN
@item --dc
Display register or balance in debit/credit format If you use
@option{--dc} with either the @command{register} (reg) or
-@command{balance} (bal) commands, you will now get extra columns.
+@command{balance} (bal) commands, you will now get extra columns.
The register goes from this:
@smallexample
@@ -6225,8 +6232,8 @@ in the register and prices reports.
Display only lines that satisfy the expression @var{EXPR}.
@item --display-amount @var{EXPR}
-Apply a transformation to the @emph{displayed} amount. This happens after
-calculations occur.
+Apply a transformation to the @emph{displayed} amount. This happens
+after calculations occur.
@item --display-total @var{EXPR}
Apply a transformation to the @emph{displayed} total. This happens after
@@ -6312,8 +6319,8 @@ or @code{commodity}. The @code{tags()} function is also useful here.
@item --group-title-format @var{FORMAT_STRING}
Set the format for the headers that separates the report sections of
-a grouped report. Only has an effect with a @option{--group-by @var{EXPR}}
-register report.
+a grouped report. Only has an effect with a @option{--group-by
+@var{EXPR}} register report.
@smallexample
$ ledger reg Expenses --group-by "payee" --group-title-format "------------------------ %-20(value) ---------------------\n"
@@ -6449,7 +6456,7 @@ Only works for accounts that have a single commodity.
Define a period expression that sets the time period during which
transactions are to be accounted. For a @command{register} report only
the transactions that satisfy the period expression with be displayed.
-For a @command{balance} report only those transactions will be accounted
+For a @command{balance} report only those transactions will be accounted
in the final balances.
@item --pivot @var{TAG}
@@ -6460,7 +6467,7 @@ identifying which car the purchase was for @samp{; Car: Prius}, then the
command:
@smallexample
-$ ledger bal Fuel --pivot "Car" --period "this year"
+$ ledger bal Fuel --pivot "Car" --period "this year"
$ 3491.26 Car
$ 1084.22 M3:Expenses:Auto:Fuel
$ 149.65 MG V11:Expenses:Auto:Fuel
@@ -6509,10 +6516,10 @@ Report commodity totals (this is the default).
Synonym for @samp{--period "quarterly"}.
@item --raw
-In the @command{print} report, show transactions using the exact same syntax as
-specified by the user in their data file. Don't do any massaging or
-interpreting. This can be useful for minor cleanups, like just aligning
-amounts.
+In the @command{print} report, show transactions using the exact same
+syntax as specified by the user in their data file. Don't do any
+massaging or interpreting. This can be useful for minor cleanups, like
+just aligning amounts.
@item --real
@itemx -R
@@ -6523,8 +6530,8 @@ transactions.
Define the output format for the @command{register} report.
@item --related
-In a @command{register} report show the related account. This is the other
-@emph{side} of the transaction.
+In a @command{register} report show the related account. This is the
+other @emph{side} of the transaction.
@item --related-all
Show all postings in a transaction, similar to @option{--related} but
@@ -6544,12 +6551,13 @@ FIX THIS ENTRY
FIX THIS ENTRY @c FIXME thdox
@item --seed @var{FIXME}
-Set the random seed to @var{FIXME} for the @code{generate} command. Used as part of
-development testing.
+Set the random seed to @var{FIXME} for the @code{generate} command.
+Used as part of development testing.
@item --sort @var{VEXPR}
@itemx -S @var{VEXPR}
-Sort the @command{register} report based on the value expression given to sort.
+Sort the @command{register} report based on the value expression given
+to sort.
@item --sort-all @var{FIXME}
FIX THIS ENTRY
@@ -6569,8 +6577,8 @@ FIX THIS ENTRY
@item --tail @var{INT}
@itemx --last @var{INT}
-Report only the last @var{INT} entries. Only useful in a @command{register}
-report.
+Report only the last @var{INT} entries. Only useful in
+a @command{register} report.
@item --time-report
FIX THIS ENTRY @c FIXME thdox
@@ -6722,8 +6730,8 @@ Set the reporting period to @var{STR}. This will subtotal all matching
transactions within each period separately, making it easy to see
weekly, monthly, quarterly, etc., posting totals. A period string can
even specify the beginning and end of the report range, using simple
-terms like @samp{last June} or @samp{next month}. For more details on period
-expressions, see @ref{Period Expressions}.
+terms like @samp{last June} or @samp{next month}. For more details on
+period expressions, see @ref{Period Expressions}.
@item --period-sort @var{VEXPR}
Sort the postings within each reporting period using the value
@@ -6856,7 +6864,7 @@ Set the value expression used for the ``totals'' column in the
@c ledger reg food not dining expr 'payee =~ /chang/'
@c @end smallexample
-@node Output customization, Commodity reporting, Report filtering, Detailed Option Description
+@node Output customization, Commodity reporting, Report filtering, Detailed Option Description
@subsection Output customization
These options affect only the output, but not which postings are
@@ -6894,7 +6902,8 @@ Report posting totals by month.
@item --yearly
@itemx -Y
-Report posting totals by year. For more complex periods, use @option{--period}.
+Report posting totals by year. For more complex periods, use
+@option{--period}.
@c TODO end this sentence
@item --period @var{PERIOD_EXPRESSION}
@@ -6907,10 +6916,10 @@ to see if weekend spending is more than on weekdays.
@item --sort @var{VEXPR}
@itemx -S @var{VEXPR}
Sort a report by comparing the values determined using the value
-expression @var{VEXPR}. For example, using @samp{-S "-abs(total)"} in the
-@command{balance} report will sort account balances from greatest to least,
-using the absolute value of the total. For more on how to use value expressions,
-see @ref{Value Expressions}.
+expression @var{VEXPR}. For example, using @samp{-S "-abs(total)"} in
+the @command{balance} report will sort account balances from greatest to
+least, using the absolute value of the total. For more on how to use
+value expressions, see @ref{Value Expressions}.
@item --pivot @var{TAG}
Produce a pivot table around the @var{TAG} provided. This requires
@@ -7296,7 +7305,7 @@ which allows you to report most everything in EUR if you use @samp{-X
EUR}, except for certain accounts or postings which should always be
valuated in another currency. For example:
-@c TODO is this example missing the actual line to get the effect?
+@c TODO is this example missing the actual line to get the effect?
@c it looks like it only contains a match, but no effect
@smallexample @c input:validate
= /^Assets:Brokerage:CAD$/
@@ -7334,13 +7343,14 @@ these values:
@itemize
@item Register Report
-For the @command{register} report, use the value of that commodity on the date of
-the posting being reported, with a @samp{<Revalued>} posting added at
-the end if today's value is different from the value of the last
-posting.
+For the @command{register} report, use the value of that commodity on
+the date of the posting being reported, with a @samp{<Revalued>} posting
+added at the end if today's value is different from the value of the
+last posting.
@item Balance Report
-For the @command{balance} report, use the value of that commodity as of today.
+For the @command{balance} report, use the value of that commodity as of
+today.
@end itemize
@@ -7353,16 +7363,16 @@ You can also now use @option{--exchange @var{COMMODITY} (-X)} (and
and @option{--price (-I)}, to see valuation reports of just your basis
costs or lot prices.
-Finally, sometimes, you may seek to only report one (or some subset)
-of the commodities in terms of another commodity. In this
-situation, you can use the syntax
-@option{--exchange @var{COMMODITY1}:@var{COMMODITY2}} to request that
-ledger always display @var{COMMODITY1} in terms of @var{COMMODITY2},
-but you want no other commodities to be automatically displayed in terms of
-@var{COMMODITY2} without additional @option{--exchange} options. For
-example, if you wanted to report EUR and BTC in terms of USD, but report
-all other commodities without conversion to USD, you could use:
-@option{--exchange EUR:USD --exchange BTC:USD}.
+Finally, sometimes, you may seek to only report one (or some subset) of
+the commodities in terms of another commodity. In this situation, you
+can use the syntax @option{--exchange @var{COMMODITY1}:@var{COMMODITY2}}
+to request that ledger always display @var{COMMODITY1} in terms of
+@var{COMMODITY2}, but you want no other commodities to be automatically
+displayed in terms of @var{COMMODITY2} without additional
+@option{--exchange} options. For example, if you wanted to report EUR
+and BTC in terms of USD, but report all other commodities without
+conversion to USD, you could use: @option{--exchange EUR:USD --exchange
+BTC:USD}.
@node Environment variables, , Commodity reporting, Detailed Option Description
@subsection Environment variables
@@ -7563,7 +7573,7 @@ This report continues outputting postings until the running total
is greater than $-500.00. A final posting is always shown, to
inform you what the total afterwards would be.
-Forecasting can also be used with the @command{balance} report,
+Forecasting can also be used with the @command{balance} report,
but by date only, and not against the running total:
@smallexample @c command:validate
@@ -7584,20 +7594,20 @@ o 2013/03/29 03:39:00
This records a check-in to the given ACCOUNT, and a check-out. You can
be checked-in to multiple accounts at a time, if you wish, and they can
span multiple days (use @option{--day-break} to break them up in the
-report). The number of seconds between check-in and check-out is accumulated
-as time to that ACCOUNT. If the checkout uses a capital @samp{O}, the
-transaction is marked ``cleared''. You can use an optional PAYEE for
-whatever meaning you like.
+report). The number of seconds between check-in and check-out is
+accumulated as time to that ACCOUNT. If the checkout uses a capital
+@samp{O}, the transaction is marked ``cleared''. You can use an
+optional PAYEE for whatever meaning you like.
Now, there are a few ways to generate this information. You can use
the @file{timeclock.el} package, which is part of Emacs. Or you can
write a simple script in whichever language you prefer to emit similar
information. Or you can use Org mode's time-clocking abilities and
-the @samp{org2tc} script developed by John Wiegley.
+the @file{org2tc} script developed by John Wiegley.
These timelog entries can appear in a separate file, or directly in
-your main ledger file. The initial @samp{i} and @samp{o} characters
-count as Ledger ``directives'', and are accepted anywhere that
+your main ledger file. The initial @samp{i} and @samp{o} characters
+count as Ledger ``directives'', and are accepted anywhere that
ordinary transactions are valid.
@node Value Expressions, Format Strings, Time Keeping, Top
@@ -7673,7 +7683,7 @@ $ ledger -b "this month" register checking
@findex --total @var{VEXPR}
Below are the one letter variables available in any value expression.
-For the @command{register} and @command{print} commands, these variables
+For the @command{register} and @command{print} commands, these variables
relate to individual postings, and sometimes the account affected by a
posting. For the @command{balance} command, these variables relate to
accounts, often with a subtle difference in meaning. The use of each
@@ -7683,10 +7693,11 @@ variable for both is specified.
@item t
This maps to whatever the user specified with @option{--amount
-@var{EXPR} (-t)}. In a @command{register} report, @option{--amount @var{EXPR}
-(-t)} changes the value column; in a @command{balance} report, it has no meaning
-by default. If @option{--amount @var{EXPR} (-t)} was not specified, the
-current report style's value expression is used.
+@var{EXPR} (-t)}. In a @command{register} report, @option{--amount
+@var{EXPR} (-t)} changes the value column; in a @command{balance}
+report, it has no meaning by default. If @option{--amount @var{EXPR}
+(-t)} was not specified, the current report style's value expression is
+used.
@item T
This maps to whatever the user specified with @option{--total
@@ -7875,15 +7886,15 @@ A regular expression that matches against a transaction's payee name.
@itemx tag(REGEX)
A regular expression that matches against a transaction's tags.
-@itemx expr date =~ /REGEX/
+@item expr date =~ /REGEX/
Useful for specifying a date in plain terms. For example, you could say
@samp{expr date =~ /2014/}.
-
@item expr comment =~ /REGEX/
-A regular expression that matches against a posting's comment field. This
-searches only a posting's field, not the transaction's note or comment field.
-For example, @samp{ledger reg "expr" "comment =~ /landline/"} will match:
+A regular expression that matches against a posting's comment
+field. This searches only a posting's field, not the transaction's note
+or comment field. For example, @code{ledger reg "expr" "comment =~
+/landline/"} will match:
@smallexample
2014/1/29 Phone bill
@@ -7906,8 +7917,8 @@ instead.
@item expr note =~ /REGEX/
A regular expression that matches against a transaction's note field.
This searches all comments in the transaction, including comments on
-individual postings. Thus, @samp{ledger reg "expr" "note =~ /landline/"} will
-match both all the three examples below:
+individual postings. Thus, @samp{ledger reg "expr" "note =~ /landline/"}
+will match both all the three examples below:
@smallexample
2014/1/29 Phone bill
@@ -7935,21 +7946,20 @@ A sub-expression is nested in parenthesis. This can be useful passing
more complicated arguments to functions, or for overriding the natural
precedence order of operators.
-
-@itemx expr base =~ /REGEX/
+@item expr base =~ /REGEX/
A regular expression that matches against an account's base name. If
a posting, this will match against the account affected by the
posting.
-@itemx expr code =~ /REGEX/
+@item expr code =~ /REGEX/
A regular expression that matches against the transaction code (the
text that occurs between parentheses before the payee).
@end table
-The @samp{query} command can be used to see how Ledger interprets your query.
-This can be useful if you are not getting the results you expect. See
-@pxref{Pre-Commands} for more.
+The @command{query} command can be used to see how Ledger interprets
+your query. This can be useful if you are not getting the results you
+expect (@pxref{Pre-Commands}).
@menu
* Miscellaneous::
@@ -8511,7 +8521,8 @@ generated the posting.
@table @code
@item filename
-the name of ledger the data file from whence the posting came, abbreviated @samp{S}.
+the name of ledger the data file from whence the posting came,
+abbreviated @samp{S}.
@item beg_pos
character position in @code{filename} where entry for posting begins,
@@ -8798,7 +8809,7 @@ amount could be an expression, etc.
@item Journal transactions
-Postings are owned by transactions, always. This subclass of item_t
+Postings are owned by transactions, always. This subclass of @code{item_t}
knows about the date, the payee, etc. If a date or metadata tag is
requested from a posting and it doesn't have that information, the
transaction is queried to see if it can provide it.
@@ -8813,14 +8824,14 @@ it, but contains relatively little information of its own.
Finally, all transactions with their postings, and all accounts, are
owned by a @code{journal_t} object. This is the go-to object for
-querying ad reporting on your data.
+querying and reporting on your data.
@item Textual journal parser
-There is a textual parser, wholly contained in @file{textual.cc}, which knows
-how to parse text into journal objects, which then get ``finalized'' and
-added to the journal. Finalization is the step that enforces the
-double-entry guarantee.
+There is a textual parser, wholly contained in @file{textual.cc}, which
+knows how to parse text into journal objects, which then get
+``finalized'' and added to the journal. Finalization is the step that
+enforces the double-entry guarantee.
@item Iterators
@@ -8838,8 +8849,8 @@ the user passed to @option{--sort @var{VEXPR}}.
Many reports bring pseudo-journal objects into existence, like postings
which report totals in a @samp{Total} account. These objects are
-created and managed by a @code{temporaries_t} object, which gets used in many
-places by the reporting filters.
+created and managed by a @code{temporaries_t} object, which gets used in
+many places by the reporting filters.
@item Option handling
@@ -9249,31 +9260,33 @@ data during the run. The following are the available @var{CODES} to
debug:
@multitable @columnfractions .32 .43 .27
-@item @code{account.display} @tab @code{expr.calc.when} @tab @code{org.next_amount}
-@item @code{accounts.sorted} @tab @code{expr.compile} @tab @code{org.next_total}
-@item @code{amount.convert} @tab @code{filters.changed_value} @tab @code{parser.error}
-@item @code{amount.is_zero} @tab @code{filters.changed_value.rounding} @tab @code{pool.commodities}
-@item @code{amount.parse} @tab @code{filters.collapse} @tab @code{post.assign}
-@item @code{amount.price} @tab @code{filters.forecast} @tab @code{python.init}
-@item @code{amount.truncate} @tab @code{filters.revalued} @tab @code{python.interp}
-@item @code{amount.unround} @tab @code{format.abbrev} @tab @code{query.mask}
-@item @code{amounts.commodities} @tab @code{format.expr} @tab @code{report.predicate}
-@item @code{amounts.refs} @tab @code{generate.post} @tab @code{scope.symbols}
-@item @code{archive.journal} @tab @code{generate.post.string} @tab @code{textual.include}
-@item @code{auto.columns} @tab @code{item.meta} @tab @code{textual.parse}
-@item @code{budget.generate} @tab @code{ledger.read} @tab @code{timelog}
-@item @code{commodity.annotated.strip} @tab @code{ledger.validate} @tab @code{times.epoch}
-@item @code{commodity.annotations} @tab @code{lookup} @tab @code{times.interval}
-@item @code{commodity.compare} @tab @code{lookup.account} @tab @code{times.parse}
-@item @code{commodity.download} @tab @code{mask.match} @tab @code{value.sort}
-@item @code{commodity.prices.add} @tab @code{memory.counts} @tab @code{value.storage.refcount}
-@item @code{commodity.prices.find} @tab @code{memory.counts.live} @tab @code{xact.extend}
-@item @code{convert.csv} @tab @code{memory.debug} @tab @code{xact.extend.cleared}
-@item @code{csv.mappings} @tab @code{op.cons} @tab @code{xact.extend.fail}
-@item @code{csv.parse} @tab @code{op.memory} @tab @code{xact.finalize}
-@item @code{draft.xact} @tab @code{option.args}
-@item @code{expr.calc} @tab @code{option.names}
+@item @code{account.display} @tab @code{draft.xact} @tab @code{option.names}
+@item @code{account.sorted} @tab @code{expr.calc} @tab @code{org.next_amount}
+@item @code{amount.commodities} @tab @code{expr.compile} @tab @code{org.next_total}
+@item @code{amount.convert} @tab @code{expr.merged.compile} @tab @code{parser.error}
+@item @code{amount.is_zero} @tab @code{filters.changed_value} @tab @code{pool.commodities}
+@item @code{amount.parse} @tab @code{filters.changed_value.rounding} @tab @code{post.assign}
+@item @code{amount.price} @tab @code{filters.collapse} @tab @code{python.init}
+@item @code{amount.refs} @tab @code{filters.forecast} @tab @code{python.interp}
+@item @code{amount.roundto} @tab @code{filters.interval} @tab @code{query.mask}
+@item @code{amount.truncate} @tab @code{filters.revalued} @tab @code{report.predicate}
+@item @code{amount.unround} @tab @code{format.abbrev} @tab @code{scope.search}
+@item @code{annotate.less} @tab @code{format.expr} @tab @code{scope.symbols}
+@item @code{archive.journal} @tab @code{generate.post} @tab @code{select.parse}
+@item @code{auto.columns} @tab @code{generate.post.string} @tab @code{textual.include}
+@item @code{budget.generate} @tab @code{history.find} @tab @code{textual.parse}
+@item @code{commodity.annotated.strip} @tab @code{history.map} @tab @code{timelog}
+@item @code{commodity.annotations} @tab @code{item.meta} @tab @code{times.epoch}
+@item @code{commodity.compare} @tab @code{ledger.read} @tab @code{times.interval}
+@item @code{commodity.download} @tab @code{ledger.validate} @tab @code{times.parse}
+@item @code{commodity.exchange} @tab @code{lookup} @tab @code{value.sort}
+@item @code{commodity.price.find} @tab @code{lookup.account} @tab @code{value.storage.refcount}
+@item @code{commodity.prices.add} @tab @code{mask.match} @tab @code{xact.extend}
+@item @code{commodity.prices.find} @tab @code{memory.debug} @tab @code{xact.extend.cleared}
+@item @code{csv.mappings} @tab @code{op.memory} @tab @code{xact.extend.fail}
+@item @code{csv.parse} @tab @code{option.args} @tab @code{xact.finalize}
@end multitable
+@
@item --trace @var{INT}
Enable tracing. The @var{INT} specifies the level of trace desired:
@@ -9292,14 +9305,15 @@ Enable tracing. The @var{INT} specifies the level of trace desired:
@item @code{LOG_TRACE} @tab 10
@item @code{LOG_ALL} @tab 11
@end multitable
+@
@item --verbose
Print detailed information on the execution of Ledger.
@item --verify
Enable additional assertions during run-time. This causes a significant
-slowdown. When combined with @option{--debug @var{CODE}} ledger will produce
-memory trace information.
+slowdown. When combined with @option{--debug @var{CODE}} ledger will
+produce memory trace information.
@item --verify-memory
FIX THIS ENTRY @c FIXME thdox
@@ -9403,8 +9417,8 @@ true
FIX THIS ENTRY @c FIXME thdox
@item template
-Shows the insertion template that the @command{xact} sub-command generates.
-This is a debugging command.
+Shows the insertion template that the @command{xact} sub-command
+generates. This is a debugging command.
@end ftable
@@ -9453,7 +9467,7 @@ where the regex matches the name of the test you want to build.
There are nearly 300 tests stored under the @file{test} subdirectory
in the main source distribution. They are broken into two broad
categories, baseline and regression. To run the @file{5FBF2ED8} test,
-for example, issue @samp{ctest -V -R "5FB"}.
+for example, issue @code{ctest -V -R "5FB"}.
@node Writing Tests, , Running Tests, Testing Framework
@subsubsection Writing Tests
@@ -9507,7 +9521,7 @@ is now @env{LEDGER_PRICE_EXP}.
@end itemize
-@node Example Journal File, Miscellaneous Notes, Major Changes from version 2.6, Top
+@node Example Journal File, Miscellaneous Notes, Major Changes from version 2.6, Top
@appendix Example Journal File
The following journal file is included with the source distribution of
@@ -9603,10 +9617,10 @@ to the main body of the documentation.
@smallexample
$ ledger --group-by "tag('trip')" bal
-$ legder reg --sort "tag('foo')" %foo
+$ ledger reg --sort "tag('foo')" %foo
$ ledger cleared VWCU NFCU Tithe Misentry
$ ledger register Joint --uncleared
-$ ledger register Checking --sort d -d 'd>[2011/04/01]' until 2011/05/25
+$ ledger register Checking --sort d -d 'd>[2011/04/01]' until 2011/05/25
@end smallexample
@node Ledger Files, , Invoking Ledger, Cookbook
diff --git a/lisp/CMakeLists.txt b/lisp/CMakeLists.txt
index 76f221b4..9dee2abb 100644
--- a/lisp/CMakeLists.txt
+++ b/lisp/CMakeLists.txt
@@ -2,9 +2,12 @@ set(EMACS_LISP_SOURCES
ledger-commodities.el
ledger-complete.el
ledger-exec.el
+ ledger-fontify.el
ledger-fonts.el
+ ledger-fontify.el
ledger-init.el
ledger-mode.el
+ ledger-navigate.el
ledger-occur.el
ledger-post.el
ledger-reconcile.el
diff --git a/lisp/ledger-commodities.el b/lisp/ledger-commodities.el
index e6f5417d..5ffebf3b 100644
--- a/lisp/ledger-commodities.el
+++ b/lisp/ledger-commodities.el
@@ -1,6 +1,6 @@
;;; ledger-commodities.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
@@ -33,11 +33,6 @@
:type 'string
:group 'ledger-reconcile)
-(defcustom ledger-scale 10000
- "The 10 ^ maximum number of digits you would expect to appear in your reports.
-This is a cheap way of getting around floating point silliness in subtraction"
- :group 'ledger)
-
(defun ledger-split-commodity-string (str)
"Split a commoditized string, STR, into two parts.
Returns a list with (value commodity)."
@@ -86,11 +81,7 @@ Returns a list with (value commodity)."
(defun -commodity (c1 c2)
"Subtract C2 from C1, ensuring their commodities match."
(if (string= (cadr c1) (cadr c2))
- ; the scaling below is to get around inexact
- ; subtraction results where, for example 1.23
- ; - 4.56 = -3.3299999999999996 instead of
- ; -3.33
- (list (/ (- (* ledger-scale (car c1)) (* ledger-scale (car c2))) ledger-scale) (cadr c1))
+ (list (-(car c1) (car c2)) (cadr c1))
(error "Can't subtract different commodities %S from %S" c2 c1)))
(defun +commodity (c1 c2)
@@ -100,22 +91,21 @@ Returns a list with (value commodity)."
(error "Can't add different commodities, %S to %S" c1 c2)))
(defun ledger-strip (str char)
- (let (new-str)
- (concat (dolist (ch (append str nil) new-str)
- (unless (= ch char)
- (setq new-str (append new-str (list ch))))))))
+ "Return STR with CHAR removed."
+ (replace-regexp-in-string char "" str))
(defun ledger-string-to-number (str &optional decimal-comma)
"improve builtin string-to-number by handling internationalization, and return nil if number can't be parsed"
(let ((nstr (if (or decimal-comma
(assoc "decimal-comma" ledger-environment-alist))
- (ledger-strip str ?.)
- (ledger-strip str ?,))))
+ (ledger-strip str ".")
+ (ledger-strip str ","))))
(while (string-match "," nstr) ;if there is a comma now, it is a thousands separator
(setq nstr (replace-match "." nil nil nstr)))
(string-to-number nstr)))
(defun ledger-number-to-string (n &optional decimal-comma)
+ "number-to-string that handles comma as decimal."
(let ((str (number-to-string n)))
(when (or decimal-comma
(assoc "decimal-comma" ledger-environment-alist))
@@ -134,6 +124,7 @@ longer ones are after the value."
(concat commodity " " str))))
(defun ledger-read-commodity-string (prompt)
+ "Read an amount from mini-buffer using PROMPT."
(let ((str (read-from-minibuffer
(concat prompt " (" ledger-reconcile-default-commodity "): ")))
comm)
diff --git a/lisp/ledger-complete.el b/lisp/ledger-complete.el
index bc4b1854..2fae9911 100644
--- a/lisp/ledger-complete.el
+++ b/lisp/ledger-complete.el
@@ -1,6 +1,6 @@
;;; ledger-complete.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
@@ -157,9 +157,7 @@
(ledger-accounts)))))
(defun ledger-trim-trailing-whitespace (str)
- (let ((s str))
- (when (string-match "[ \t]*$" s)
- (replace-match "" nil nil s))))
+ (replace-regexp-in-string "[ \t]*$" "" str))
(defun ledger-fully-complete-xact ()
"Completes a transaction if there is another matching payee in the buffer.
diff --git a/lisp/ledger-context.el b/lisp/ledger-context.el
index 7b10c552..0dfa4645 100644
--- a/lisp/ledger-context.el
+++ b/lisp/ledger-context.el
@@ -1,6 +1,6 @@
;;; ledger-context.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
@@ -44,9 +44,11 @@
(defconst ledger-payee-string "\\(.*\\)")
(defun ledger-get-regex-str (name)
+ "Get the ledger regex of type NAME."
(symbol-value (intern (concat "ledger-" (symbol-name name) "-string"))))
(defun ledger-line-regex (elements)
+ "Get a regex to match ELEMENTS on a single line."
(concat (apply 'concat (mapcar 'ledger-get-regex-str elements)) "[ \t]*$"))
(defmacro ledger-single-line-config (&rest elements)
@@ -195,4 +197,4 @@ specified line, returns nil."
(provide 'ledger-context)
-;;; ledger-report.el ends here
+;;; ledger-context.el ends here
diff --git a/lisp/ledger-exec.el b/lisp/ledger-exec.el
index cd5c11a0..8902d839 100644
--- a/lisp/ledger-exec.el
+++ b/lisp/ledger-exec.el
@@ -1,6 +1,6 @@
;;; ledger-exec.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
@@ -36,7 +36,7 @@
:group 'ledger)
(defcustom ledger-mode-should-check-version t
- "Should Ledger-mode verify that the executable is working"
+ "Should Ledger-mode verify that the executable is working?"
:type 'boolean
:group 'ledger-exec)
@@ -53,6 +53,7 @@
(setq buffer-read-only t)))
(defun ledger-exec-success-p (ledger-output-buffer)
+ "Return t if the ledger output in LEDGER-OUTPUT-BUFFER is successful."
(with-current-buffer ledger-output-buffer
(goto-char (point-min))
(if (and (> (buffer-size) 1) (looking-at (regexp-quote "While")))
diff --git a/lisp/ledger-fontify.el b/lisp/ledger-fontify.el
new file mode 100644
index 00000000..d307208f
--- /dev/null
+++ b/lisp/ledger-fontify.el
@@ -0,0 +1,199 @@
+;;; ledger-fontify.el --- Provide custom fontification for ledger-mode
+
+
+;; Copyright (C) 2014 Craig P. Earls (enderw88 at gmail dot com)
+
+;; This file is not part of GNU Emacs.
+
+;; This is free software; you can redistribute it and/or modify it under
+;; the terms of the GNU General Public License as published by the Free
+;; Software Foundation; either version 2, or (at your option) any later
+;; version.
+;;
+;; This is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+;; for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+;; MA 02110-1301 USA.
+
+;;; Commentary:
+;; Font-lock-mode doesn't handle multiline syntax very well. This
+;; code provides font lock that is sensitive to overall transaction
+;; states
+
+
+;;; Code:
+
+(require 'ledger-navigate)
+(require 'ledger-regex)
+(require 'ledger-state)
+
+(defcustom ledger-fontify-xact-state-overrides nil
+ "If t the highlight entire xact with state."
+ :type 'boolean
+ :group 'ledger)
+
+(defun ledger-fontify-buffer-part (&optional beg end len)
+"Fontify buffer from BEG to END, length LEN."
+ (save-excursion
+ (unless beg (setq beg (point-min)))
+ (unless end (setq end (point-max)))
+ (beginning-of-line)
+ (while (< (point) end)
+ (cond ((or (looking-at ledger-xact-start-regex)
+ (looking-at ledger-posting-regex))
+ (ledger-fontify-xact-at (point)))
+ ((looking-at ledger-directive-start-regex)
+ (ledger-fontify-directive-at (point))))
+ (ledger-navigate-next-xact-or-directive))))
+
+(defun ledger-fontify-xact-at (position)
+ "Fontify the xact at POSITION."
+ (interactive "d")
+ (save-excursion
+ (goto-char position)
+ (let ((extents (ledger-navigate-find-element-extents position))
+ (state (ledger-transaction-state)))
+ (if (and ledger-fontify-xact-state-overrides state)
+ (cond ((eq state 'cleared)
+ (ledger-fontify-set-face extents 'ledger-font-xact-cleared-face))
+ ((eq state 'pending)
+ (ledger-fontify-set-face extents 'ledger-font-xact-pending-face)))
+ (ledger-fontify-xact-by-line extents)))))
+
+(defun ledger-fontify-xact-by-line (extents)
+ "Do line-by-line detailed fontification of xact in EXTENTS."
+ (save-excursion
+ (ledger-fontify-xact-start (car extents))
+ (while (< (point) (cadr extents))
+ (if (looking-at "[ \t]+;")
+ (ledger-fontify-set-face (list (point) (progn
+ (end-of-line)
+ (point))) 'ledger-font-comment-face)
+ (ledger-fontify-posting (point)))
+ (forward-line))))
+
+(defun ledger-fontify-xact-start (pos)
+ "POS should be at the beginning of a line starting an xact.
+Fontify the first line of an xact"
+ (goto-char pos)
+ (let ((line-start (line-beginning-position)))
+ (goto-char line-start)
+ (re-search-forward "[ \t]")
+ (ledger-fontify-set-face (list line-start (match-beginning 0)) 'ledger-font-posting-date-face)
+ (goto-char line-start)
+ (re-search-forward ledger-xact-after-date-regex)
+ (let ((state (save-match-data (ledger-state-from-string (match-string 1)))))
+ (ledger-fontify-set-face (list (match-beginning 3) (match-end 3))
+ (cond ((eq state 'pending)
+ 'ledger-font-payee-pending-face)
+ ((eq state 'cleared)
+ 'ledger-font-payee-cleared-face)
+ (t
+ 'ledger-font-payee-uncleared-face))))
+ (when (match-beginning 4)
+ (ledger-fontify-set-face (list (match-beginning 4)
+ (match-end 4)) 'ledger-font-comment-face))
+ (forward-line)))
+
+(defun ledger-fontify-posting (pos)
+ "Fontify the posting at POS."
+ (let* ((state nil)
+ (end-of-line-comment nil)
+ (end (progn (end-of-line)
+ (point)))
+ (start (progn (beginning-of-line)
+ (point))))
+
+ ;; Look for a posting status flag
+ (set-match-data nil 'reseat)
+ (re-search-forward " \\([*!]\\) " end t)
+ (if (match-string 1)
+ (setq state (ledger-state-from-string (match-string 1))))
+ (beginning-of-line)
+ (re-search-forward "[[:graph:]]\\([ \t][ \t]\\)" end 'end) ;; find the end of the account, or end of line
+
+ (when (<= (point) end) ;; we are still on the line
+ (ledger-fontify-set-face (list start (point))
+ (cond ((eq state 'cleared)
+ 'ledger-font-posting-account-cleared-face)
+ ((eq state 'pending)
+ 'ledger-font-posting-account-pending-face)
+ (t
+ 'ledger-font-posting-account-face)))
+
+
+ (when (< (point) end) ;; there is still more to fontify
+ (setq start (point)) ;; update start of next font region
+ (setq end-of-line-comment (re-search-forward ";" end 'end)) ;; find the end of the line, or start of a comment
+ (ledger-fontify-set-face (list start (point) )
+ (cond ((eq state 'cleared)
+ 'ledger-font-posting-amount-cleared-face)
+ ((eq state 'pending)
+ 'ledger-font-posting-amount-pending-face)
+ (t
+ 'ledger-font-posting-amount-face)))
+ (when end-of-line-comment
+ (setq start (point))
+ (end-of-line)
+ (ledger-fontify-set-face (list (- start 1) (point)) ;; subtract 1 from start because we passed the semi-colon
+ 'ledger-font-comment-face))))))
+
+(defun ledger-fontify-directive-at (pos)
+ "Fontify the directive at POS."
+ (let ((extents (ledger-navigate-find-element-extents pos))
+ (face 'ledger-font-default-face))
+ (cond ((looking-at "=")
+ (setq face 'ledger-font-auto-xact-face))
+ ((looking-at "~")
+ (setq face 'ledger-font-periodic-xact-face))
+ ((looking-at "[;#%|\\*]")
+ (setq face 'ledger-font-comment-face))
+ ((looking-at "\\(year\\)\\|Y")
+ (setq face 'ledger-font-year-directive-face))
+ ((looking-at "account")
+ (setq face 'ledger-font-account-directive-face))
+ ((looking-at "apply")
+ (setq face 'ledger-font-apply-directive-face))
+ ((looking-at "alias")
+ (setq face 'ledger-font-alias-directive-face))
+ ((looking-at "assert")
+ (setq face 'ledger-font-assert-directive-face))
+ ((looking-at "\\(bucket\\)\\|A")
+ (setq face 'ledger-font-bucket-directive-face))
+ ((looking-at "capture")
+ (setq face 'ledger-font-capture-directive-face))
+ ((looking-at "check")
+ (setq face 'ledger-font-check-directive-face))
+ ((looking-at "commodity")
+ (setq face 'ledger-font-commodity-directive-face))
+ ((looking-at "define")
+ (setq face 'ledger-font-define-directive-face))
+ ((looking-at "end")
+ (setq face 'ledger-font-end-directive-face))
+ ((looking-at "expr")
+ (setq face 'ledger-font-expr-directive-face))
+ ((looking-at "fixed")
+ (setq face 'ledger-font-fixed-directive-face))
+ ((looking-at "include")
+ (setq face 'ledger-font-include-directive-face))
+ ((looking-at "payee")
+ (setq face 'ledger-font-payee-directive-face))
+ ((looking-at "P")
+ (setq face 'ledger-font-price-directive-face))
+ ((looking-at "tag")
+ (setq face 'ledger-font-tag-directive-face)))
+ (ledger-fontify-set-face extents face)))
+
+(defun ledger-fontify-set-face (extents face)
+ "Set the text in EXTENTS to FACE."
+ (put-text-property (car extents) (cadr extents) 'face face))
+
+
+(provide 'ledger-fontify)
+
+;;; ledger-fontify.el ends here
diff --git a/lisp/ledger-fonts.el b/lisp/ledger-fonts.el
index f5ed6e94..8bdecdb3 100644
--- a/lisp/ledger-fonts.el
+++ b/lisp/ledger-fonts.el
@@ -1,6 +1,6 @@
;;; ledger-fonts.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
@@ -29,6 +29,37 @@
(require 'ledger-regex)
(defgroup ledger-faces nil "Ledger mode highlighting" :group 'ledger)
+
+(defface ledger-font-default-face
+ `((t :inherit default))
+ "Default face"
+ :group 'ledger-faces)
+
+(defface ledger-font-auto-xact-face
+ `((t :foreground "orange" :weight normal))
+ "Default face for automatic transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-periodic-xact-face
+ `((t :foreground "green" :weight normal))
+ "Default face for automatic transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-xact-cleared-face
+ `((t :foreground "#AAAAAA" :weight normal))
+ "Default face for cleared transaction"
+ :group 'ledger-faces)
+
+(defface ledger-font-xact-pending-face
+ `((t :foreground "#444444" :weight normal))
+ "Default face for pending transaction"
+ :group 'ledger-faces)
+
+(defface ledger-font-xact-open-face
+ `((t :foreground "#000000" :weight normal))
+ "Default face for transaction under point"
+ :group 'ledger-faces)
+
(defface ledger-font-payee-uncleared-face
`((t :foreground "#dc322f" :weight bold ))
"Default face for Ledger"
@@ -36,7 +67,12 @@
(defface ledger-font-payee-cleared-face
`((t :inherit ledger-font-other-face))
- "Default face for cleared (*) transactions"
+ "Default face for cleared (*) payees"
+ :group 'ledger-faces)
+
+(defface ledger-font-payee-pending-face
+ `((t :foreground "#F24B61" :weight normal))
+ "Default face for pending (!) payees"
:group 'ledger-faces)
(defface ledger-font-xact-highlight-face
@@ -54,6 +90,96 @@
"Default face for other transactions"
:group 'ledger-faces)
+(defface ledger-font-directive-face
+ `((t :inherit font-lock-preprocessor-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-account-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-price-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-apply-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-alias-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-assert-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-bucket-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-capture-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-check-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-commodity-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-define-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-end-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-expr-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-fixed-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-include-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-payee-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-tag-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
+(defface ledger-font-year-directive-face
+ `((t :inherit ledger-font-directive-face))
+ "Default face for other transactions"
+ :group 'ledger-faces)
+
(defface ledger-font-posting-account-face
`((t :foreground "#268bd2" ))
"Face for Ledger accounts"
@@ -64,11 +190,21 @@
"Face for Ledger accounts"
:group 'ledger-faces)
+(defface ledger-font-posting-amount-cleared-face
+ `((t :inherit ledger-font-posting-account-cleared-face))
+ "Face for Ledger accounts"
+ :group 'ledger-faces)
+
(defface ledger-font-posting-account-pending-face
`((t :inherit ledger-font-pending-face))
"Face for Ledger accounts"
:group 'ledger-faces)
+(defface ledger-font-posting-amount-pending-face
+ `((t :inherit ledger-font-posting-account-pending-face))
+ "Face for Ledger accounts"
+ :group 'ledger-faces)
+
(defface ledger-font-posting-amount-face
`((t :foreground "#cb4b16" ))
"Face for Ledger amounts"
@@ -80,18 +216,17 @@
:group 'ledger-faces)
(defface ledger-occur-narrowed-face
- `((t :foreground "grey70" :invisible t ))
+ `((t :inherit font-lock-comment-face :invisible t))
"Default face for Ledger occur mode hidden transactions"
:group 'ledger-faces)
(defface ledger-occur-xact-face
- `((((background dark)) :background "#1a1a1a" )
- (t :background "#eee8d5" ))
+ `((t :inherit highlight))
"Default face for Ledger occur mode shown transactions"
:group 'ledger-faces)
(defface ledger-font-comment-face
- `((t :foreground "#93a1a1" :slant italic))
+ `((t :inherit font-lock-comment-face))
"Face for Ledger comments"
:group 'ledger-faces)
@@ -115,30 +250,25 @@
"Default face for pending (!) transactions in the reconcile window"
:group 'ledger-faces)
+ (defvar ledger-font-lock-keywords
+ `(("account" . ledger-font-account-directive-face)
+ ("apply" . ledger-font-apply-directive-face)
+ ("alias" . ledger-font-alias-directive-face)
+ ("assert" . ledger-font-assert-directive-face)
+ ("bucket" . ledger-font-bucket-directive-face)
+ ("capture" . ledger-font-capture-directive-face)
+ ("check" . ledger-font-check-directive-face)
+ ("commodity" . ledger-font-commodity-directive-face)
+ ("define" . ledger-font-define-directive-face)
+ ("end" . ledger-font-end-directive-face)
+ ("expr" . ledger-font-expr-directive-face)
+ ("fixed" . ledger-font-fixed-directive-face)
+ ("include" . ledger-font-include-directive-face)
+ ("payee" . ledger-font-payee-directive-face)
+ ("tag" . ledger-font-tag-directive-face)
+ ("year" . ledger-font-year-directive-face))
+ "Expressions to highlight in Ledger mode.")
-(defvar ledger-font-lock-keywords
- `( ;; (,ledger-other-entries-regex 1
- ;; ledger-font-other-face)
- (,ledger-comment-regex 0
- 'ledger-font-comment-face)
- (,ledger-amount-regex 0
- 'ledger-font-posting-amount-face)
- (,ledger-multiline-comment-regex 0 'ledger-font-comment-face)
- (,ledger-payee-pending-regex 2
- 'ledger-font-payee-pending-face) ; Works
- (,ledger-payee-cleared-regex 2
- 'ledger-font-payee-cleared-face) ; Works
- (,ledger-payee-uncleared-regex 2
- 'ledger-font-payee-uncleared-face) ; Works
- (,ledger-account-cleared-regex 2
- 'ledger-font-posting-account-cleared-face) ; Works
- (,ledger-account-pending-regex 2
- 'ledger-font-posting-account-pending-face) ; Works
- (,ledger-account-any-status-regex 2
- 'ledger-font-posting-account-face) ; Works
- (,ledger-other-entries-regex 1
- 'ledger-font-other-face))
- "Expressions to highlight in Ledger mode.")
(provide 'ledger-fonts)
diff --git a/lisp/ledger-init.el b/lisp/ledger-init.el
index 491f20cf..49d74098 100644
--- a/lisp/ledger-init.el
+++ b/lisp/ledger-init.el
@@ -1,6 +1,6 @@
;;; ledger-init.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
@@ -24,8 +24,10 @@
(require 'ledger-regex)
+;;; Code:
+
(defcustom ledger-init-file-name "~/.ledgerrc"
- "Location of the ledger initialization file. nil if you don't have one"
+ "Location of the ledger initialization file. nil if you don't have one."
:group 'ledger-exec)
(defvar ledger-environment-alist nil)
@@ -33,6 +35,7 @@
(defvar ledger-default-date-format "%Y/%m/%d")
(defun ledger-init-parse-initialization (buffer)
+ "Parse the .ledgerrc file in BUFFER."
(with-current-buffer buffer
(let (environment-alist)
(goto-char (point-min))
@@ -53,6 +56,7 @@
environment-alist)))
(defun ledger-init-load-init-file ()
+ "Load and parse the .ledgerrc file."
(interactive)
(let ((init-base-name (file-name-nondirectory ledger-init-file-name)))
(if (get-buffer init-base-name) ;; init file already loaded, parse it and leave it
diff --git a/lisp/ledger-mode.el b/lisp/ledger-mode.el
index 458c24b1..4e2beff6 100644
--- a/lisp/ledger-mode.el
+++ b/lisp/ledger-mode.el
@@ -1,6 +1,6 @@
;;; ledger-mode.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
@@ -27,6 +27,7 @@
;;; Code:
(require 'ledger-regex)
+(require 'cus-edit)
(require 'esh-util)
(require 'esh-arg)
(require 'easymenu)
@@ -35,7 +36,9 @@
(require 'ledger-context)
(require 'ledger-exec)
(require 'ledger-fonts)
+(require 'ledger-fontify)
(require 'ledger-init)
+(require 'ledger-navigate)
(require 'ledger-occur)
(require 'ledger-post)
(require 'ledger-reconcile)
@@ -59,11 +62,12 @@
(defconst ledger-mode-version "3.0.0")
(defun ledger-mode-dump-variable (var)
- (if var
+ "Format VAR for dump to buffer."
+ (if var
(insert (format " %s: %S\n" (symbol-name var) (eval var)))))
(defun ledger-mode-dump-group (group)
- "Dump GROUP customizations to current buffer"
+ "Dump GROUP customizations to current buffer."
(let ((members (custom-group-members group nil)))
(dolist (member members)
(cond ((eq (cadr member) 'custom-group)
@@ -73,7 +77,7 @@
(ledger-mode-dump-variable (car member)))))))
(defun ledger-mode-dump-configuration ()
- "Dump all customizations"
+ "Dump all customizations."
(interactive)
(find-file "ledger-mode-dump")
(ledger-mode-dump-group 'ledger))
@@ -94,14 +98,15 @@
"Start a ledger session with the current month, but make it customizable to ease retro-entry.")
(defun ledger-read-account-with-prompt (prompt)
- (let* ((context (ledger-context-at-point))
- (default (if (eq (ledger-context-line-type context) 'acct-transaction)
- (regexp-quote (ledger-context-field-value context 'account))
- nil)))
- (ledger-read-string-with-default prompt default)))
+ "Read an account from the minibuffer with PROMPT."
+ (let ((context (ledger-context-at-point)))
+ (ledger-read-string-with-default prompt
+ (if (eq (ledger-context-current-field context) 'account)
+ (regexp-quote (ledger-context-field-value context 'account))
+ nil))))
(defun ledger-read-date (prompt)
- "Returns user-supplied date after `PROMPT', defaults to today."
+ "Return user-supplied date after `PROMPT', defaults to today."
(let* ((default (ledger-year-and-month))
(date (read-string prompt default
'ledger-minibuffer-history)))
@@ -146,7 +151,7 @@ And calculate the target-delta of the account being reconciled."
(message balance))))
(defun ledger-magic-tab (&optional interactively)
- "Decide what to with with <TAB>.
+ "Decide what to with with <TAB>, INTERACTIVELY.
Can indent, complete or align depending on context."
(interactive "p")
(if (= (point) (line-beginning-position))
@@ -164,14 +169,14 @@ Can indent, complete or align depending on context."
ledger-default-date-format)))
(defun ledger-remove-effective-date ()
- "Removes the effective date from a transaction or posting."
+ "Remove the effective date from a transaction or posting."
(interactive)
(let ((context (car (ledger-context-at-point))))
(save-excursion
(save-restriction
(narrow-to-region (point-at-bol) (point-at-eol))
(beginning-of-line)
- (cond ((eq 'pmnt-transaction context)
+ (cond ((eq 'xact context)
(re-search-forward ledger-iso-date-regexp)
(when (= (char-after) ?=)
(let ((eq-pos (point)))
@@ -194,7 +199,7 @@ If `DATE' is nil, prompt the user a date.
Replace the current effective date if there's one in the same
line.
-With a prefix argument, remove the effective date. "
+With a prefix argument, remove the effective date."
(interactive)
(if (and (listp current-prefix-arg)
(= 4 (prefix-numeric-value current-prefix-arg)))
@@ -204,7 +209,7 @@ With a prefix argument, remove the effective date. "
(save-restriction
(narrow-to-region (point-at-bol) (point-at-eol))
(cond
- ((eq 'pmnt-transaction context)
+ ((eq 'xact context)
(beginning-of-line)
(re-search-forward ledger-iso-date-regexp)
(when (= (char-after) ?=)
@@ -216,26 +221,35 @@ With a prefix argument, remove the effective date. "
(insert " ; [=" date-string "]")))))))
(defun ledger-mode-remove-extra-lines ()
- (goto-char (point-min))
+ "Get rid of multiple empty lines."
+ (goto-char (point-min))
(while (re-search-forward "\n\n\\(\n\\)+" nil t)
(replace-match "\n\n")))
(defun ledger-mode-clean-buffer ()
- "indent, remove multiple linfe feeds and sort the buffer"
+ "Indent, remove multiple line feeds and sort the buffer."
(interactive)
- (untabify (point-min) (point-max))
- (ledger-sort-buffer)
- (ledger-post-align-postings (point-min) (point-max))
- (ledger-mode-remove-extra-lines))
-
+ (let ((start (point-min-marker))
+ (end (point-max-marker)))
+ (goto-char start)
+ (ledger-navigate-beginning-of-xact)
+ (beginning-of-line)
+ (let ((target (buffer-substring (point) (progn
+ (end-of-line)
+ (point)))))
+ (untabify start end)
+ (ledger-sort-buffer)
+ (ledger-post-align-postings start end)
+ (ledger-mode-remove-extra-lines)
+ (goto-char start)
+ (search-forward target))))
(defvar ledger-mode-syntax-table
- (let ((table (make-syntax-table)))
- ;; Support comments via the syntax table
- (modify-syntax-entry ?\; "< b" table)
- (modify-syntax-entry ?\n "> b" table)
+ (let ((table (make-syntax-table text-mode-syntax-table)))
+ (modify-syntax-entry ?\; "<" table)
+ (modify-syntax-entry ?\n ">" table)
table)
- "Syntax table for `ledger-mode' buffers.")
+ "Syntax table in use in `ledger-mode' buffers.")
(defvar ledger-mode-map
(let ((map (make-sparse-keymap)))
@@ -269,8 +283,8 @@ With a prefix argument, remove the effective date. "
(define-key map [(control ?c) (control ?o) (control ?r)] 'ledger-report)
(define-key map [(control ?c) (control ?o) (control ?s)] 'ledger-report-save)
- (define-key map [(meta ?p)] 'ledger-post-prev-xact)
- (define-key map [(meta ?n)] 'ledger-post-next-xact)
+ (define-key map [(meta ?p)] 'ledger-navigate-prev-xact-or-directive)
+ (define-key map [(meta ?n)] 'ledger-navigate-next-xact-or-directive)
map)
"Keymap for `ledger-mode'.")
@@ -278,9 +292,10 @@ With a prefix argument, remove the effective date. "
"Ledger menu"
'("Ledger"
["Narrow to REGEX" ledger-occur]
+ ["Show all transactions" ledger-occur-mode ledger-occur-mode]
["Ledger Statistics" ledger-display-ledger-stats ledger-works]
"---"
- ["Show upcoming transactions" ledger-schedule-upcoming ledger-schedule-available]
+ ["Show upcoming transactions" ledger-schedule-upcoming]
["Add Transaction (ledger xact)" ledger-add-transaction ledger-works]
["Complete Transaction" ledger-fully-complete-xact]
["Delete Transaction" ledger-delete-current-transaction]
@@ -318,37 +333,25 @@ With a prefix argument, remove the effective date. "
(define-derived-mode ledger-mode text-mode "Ledger"
"A mode for editing ledger data files."
(ledger-check-version)
- (ledger-schedule-check-available)
- ;;(ledger-post-setup)
-
- (set-syntax-table ledger-mode-syntax-table)
- (set (make-local-variable 'comment-start) "; ")
- (set (make-local-variable 'comment-end) "")
- (set (make-local-variable 'indent-tabs-mode) nil)
-
- (if (boundp 'font-lock-defaults)
- (set (make-local-variable 'font-lock-defaults)
- '(ledger-font-lock-keywords nil t)))
- (setq font-lock-extend-region-functions
- (list #'font-lock-extend-region-wholelines))
- (setq font-lock-multiline nil)
-
- (set (make-local-variable 'pcomplete-parse-arguments-function)
- 'ledger-parse-arguments)
- (set (make-local-variable 'pcomplete-command-completion-function)
- 'ledger-complete-at-point)
+ (when (boundp 'font-lock-defaults)
+ (setq font-lock-defaults
+ '(ledger-font-lock-keywords t t nil nil
+ (font-lock-fontify-region-function . ledger-fontify-buffer-part))))
+
+ (set (make-local-variable 'pcomplete-parse-arguments-function) 'ledger-parse-arguments)
+ (set (make-local-variable 'pcomplete-command-completion-function) 'ledger-complete-at-point)
(add-hook 'completion-at-point-functions 'pcomplete-completions-at-point nil t)
(add-hook 'after-save-hook 'ledger-report-redo)
- ;(add-hook 'after-save-hook)
(add-hook 'post-command-hook 'ledger-highlight-xact-under-point nil t)
- (add-hook 'before-revert-hook 'ledger-occur-remove-all-overlays nil t)
(ledger-init-load-init-file)
+ (setq comment-start ";")
(set (make-local-variable 'indent-region-function) 'ledger-post-align-postings))
+
(defun ledger-set-year (newyear)
"Set ledger's idea of the current year to the prefix argument NEWYEAR."
(interactive "p")
diff --git a/lisp/ledger-navigate.el b/lisp/ledger-navigate.el
new file mode 100644
index 00000000..904faf8c
--- /dev/null
+++ b/lisp/ledger-navigate.el
@@ -0,0 +1,168 @@
+;;; ledger-navigate.el --- Provide navigation services through the ledger buffer.
+
+;; Copyright (C) 2014-2015 Craig Earls (enderw88 AT gmail DOT com)
+
+;; This file is not part of GNU Emacs.
+
+;; This is free software; you can redistribute it and/or modify it under
+;; the terms of the GNU General Public License as published by the Free
+;; Software Foundation; either version 2, or (at your option) any later
+;; version.
+;;
+;; This is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+;; for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+;; MA 02110-1301 USA.
+
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'ledger-regex)
+(require 'ledger-context)
+
+(defun ledger-navigate-next-xact ()
+ "Move point to beginning of next xact."
+ ;; make sure we actually move to the next xact, even if we are the
+ ;; beginning of one now.
+ (if (looking-at ledger-payee-any-status-regex)
+ (forward-line))
+ (if (re-search-forward ledger-payee-any-status-regex nil t)
+ (goto-char (match-beginning 0))
+ (goto-char (point-max))))
+
+(defun ledger-navigate-start-xact-or-directive-p ()
+ "Return t if at the beginning of an empty or all-whitespace line."
+ (not (looking-at "[ \t]\\|\\(^$\\)")))
+
+(defun ledger-navigate-next-xact-or-directive ()
+ "Move to the beginning of the next xact or directive."
+ (interactive)
+ (beginning-of-line)
+ (if (ledger-navigate-start-xact-or-directive-p) ; if we are the start of an xact, move forward to the next xact
+ (progn
+ (forward-line)
+ (if (not (ledger-navigate-start-xact-or-directive-p)) ; we have moved forward and are not at another xact, recurse forward
+ (ledger-navigate-next-xact-or-directive)))
+ (while (not (or (eobp) ; we didn't start off at the beginning of an xact
+ (ledger-navigate-start-xact-or-directive-p)))
+ (forward-line))))
+
+(defun ledger-navigate-prev-xact-or-directive ()
+ "Move point to beginning of previous xact."
+ (interactive)
+ (let ((context (car (ledger-context-at-point))))
+ (when (equal context 'acct-transaction)
+ (ledger-navigate-beginning-of-xact))
+ (beginning-of-line)
+ (re-search-backward "^[[:graph:]]" nil t)))
+
+(defun ledger-navigate-beginning-of-xact ()
+ "Move point to the beginning of the current xact."
+ (interactive)
+ ;; need to start at the beginning of a line incase we are in the first line of an xact already.
+ (beginning-of-line)
+ (let ((sreg (concat "^\\(=\\|~\\|" ledger-iso-date-regexp "\\)")))
+ (unless (looking-at sreg)
+ (re-search-backward sreg nil t)
+ (beginning-of-line)))
+ (point))
+
+(defun ledger-navigate-end-of-xact ()
+ "Move point to end of xact."
+ (interactive)
+ (ledger-navigate-next-xact-or-directive)
+ (re-search-backward ".$")
+ (end-of-line)
+ (point))
+
+(defun ledger-navigate-to-line (line-number)
+ "Rapidly move point to line LINE-NUMBER."
+ (goto-char (point-min))
+ (forward-line (1- line-number)))
+
+(defun ledger-navigate-find-xact-extents (pos)
+ "Return list containing point for beginning and end of xact containing POS.
+Requires empty line separating xacts."
+ (interactive "d")
+ (save-excursion
+ (goto-char pos)
+ (list (ledger-navigate-beginning-of-xact)
+ (ledger-navigate-end-of-xact))))
+
+(defun ledger-navigate-find-directive-extents (pos)
+ "Return the extents of the directive at POS."
+ (goto-char pos)
+ (let ((begin (progn (beginning-of-line)
+ (point)))
+ (end (progn (end-of-line)
+ (+ 1 (point)))))
+ ;; handle block comments here
+ (beginning-of-line)
+ (if (looking-at " *;")
+ (progn
+ (while (and (looking-at " *;")
+ (> (point) (point-min)))
+ (forward-line -1))
+ ;; We are either at the beginning of the buffer, or we found
+ ;; a line outside the comment. If we are not at the
+ ;; beginning of the buffer then we need to move forward a
+ ;; line.
+ (if (> (point) (point-min))
+ (progn (forward-line 1)
+ (beginning-of-line)))
+ (setq begin (point))
+ (goto-char pos)
+ (beginning-of-line)
+ (while (and (looking-at " *;")
+ (< (point) (point-max)))
+ (forward-line 1))
+ (setq end (point))))
+ (list begin end)))
+
+(defun ledger-navigate-block-comment (pos)
+ "Move past the block comment at POS, and return its extents."
+ (interactive "d")
+ (goto-char pos)
+ (let ((begin (progn (beginning-of-line)
+ (point)))
+ (end (progn (end-of-line)
+ (point))))
+ ;; handle block comments here
+ (beginning-of-line)
+ (if (looking-at " *;")
+ (progn
+ (while (and (looking-at " *;")
+ (> (point) (point-min)))
+ (forward-line -1))
+ (setq begin (point))
+ (goto-char pos)
+ (beginning-of-line)
+ (while (and (looking-at " *;")
+ (< (point) (point-max)))
+ (forward-line 1))
+ (setq end (point))))
+ (list begin end)))
+
+
+(defun ledger-navigate-find-element-extents (pos)
+ "Return list containing beginning and end of the entity surrounding POS."
+ (interactive "d")
+ (save-excursion
+ (goto-char pos)
+ (beginning-of-line)
+ (if (looking-at "[ =~0-9]")
+ (ledger-navigate-find-xact-extents pos)
+ (ledger-navigate-find-directive-extents pos))))
+
+
+(provide 'ledger-navigate)
+
+;;; ledger-navigate.el ends here
diff --git a/lisp/ledger-occur.el b/lisp/ledger-occur.el
index 9287ed13..a4fde2e1 100644
--- a/lisp/ledger-occur.el
+++ b/lisp/ledger-occur.el
@@ -1,6 +1,6 @@
-;;; ledger-mode.el --- Helper code for use with the "ledger" command-line tool
+;;; ledger-occur.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
@@ -29,6 +29,9 @@
;;; Code:
+(require 'cl)
+(require 'ledger-navigate)
+
(defconst ledger-occur-overlay-property-name 'ledger-occur-custom-buffer-grep)
(defcustom ledger-occur-use-face-shown t
@@ -38,78 +41,66 @@
(make-variable-buffer-local 'ledger-occur-use-face-shown)
-(defvar ledger-occur-mode nil
- "name of the minor mode, shown in the mode-line")
+(defvar ledger-occur-history nil
+ "History of previously searched expressions for the prompt.")
-(make-variable-buffer-local 'ledger-occur-mode)
+(defvar ledger-occur-current-regex nil
+ "Pattern currently applied to narrow the buffer.")
+(make-variable-buffer-local 'ledger-occur-current-regex)
-(or (assq 'ledger-occur-mode minor-mode-alist)
- (nconc minor-mode-alist
- (list '(ledger-occur-mode ledger-occur-mode))))
+(defvar ledger-occur-mode-map (make-sparse-keymap))
-(defvar ledger-occur-history nil
- "History of previously searched expressions for the prompt.")
+(define-minor-mode ledger-occur-mode
+ "A minor mode which display only transactions matching `ledger-occur-current-regex'."
+ nil
+ (:eval (format " Ledger-Narrow(%s)" ledger-occur-current-regex))
+ ledger-occur-mode-map
+ (if (and ledger-occur-current-regex ledger-occur-mode)
+ (ledger-occur-refresh)
+ (ledger-occur-remove-overlays)
+ (message "Showing all transactions")))
-(defvar ledger-occur-last-match nil
- "Last match found.")
-(make-variable-buffer-local 'ledger-occur-last-match)
+(define-key ledger-occur-mode-map (kbd "C-c C-g") 'ledger-occur-refresh)
+(define-key ledger-occur-mode-map (kbd "C-c C-f") 'ledger-occur-mode)
-(defun ledger-occur-remove-all-overlays ()
- "Remove all overlays from the ledger buffer."
+(defun ledger-occur-refresh ()
+ "Re-apply the current narrowing expression."
(interactive)
- (remove-overlays))
-
-(defun ledger-occur-mode (regex buffer)
- "Highlight transactions that match REGEX in BUFFER, hiding others.
-
-When REGEX is nil, unhide everything, and remove higlight"
- (set-buffer buffer)
- (setq ledger-occur-mode
- (if (or (null regex)
- (zerop (length regex)))
- nil
- (concat " Ledger-Narrowed: " regex)))
- (force-mode-line-update)
- (ledger-occur-remove-overlays)
- (when ledger-occur-mode
- (ledger-occur-create-overlays
- (ledger-occur-compress-matches
- (ledger-occur-find-matches regex)))
- (setq ledger-occur-last-match regex)
- (if (get-buffer-window buffer)
- (select-window (get-buffer-window buffer))))
- (recenter))
+ (let ((matches (ledger-occur-compress-matches
+ (ledger-occur-find-matches ledger-occur-current-regex))))
+ (if matches
+ (ledger-occur-create-overlays matches)
+ (message "No matches found for '%s'" ledger-occur-current-regex)
+ (ledger-occur-mode -1))))
(defun ledger-occur (regex)
- "Perform a simple grep in current buffer for the regular expression REGEX.
+ "Show only transactions in the current buffer which match REGEX.
- This command hides all xact from the current buffer except
- those containing the regular expression REGEX. A second call
- of the function unhides lines again"
+This command hides all xact in the current buffer except those
+matching REGEX. If REGEX is nil or empty, turn off any narrowing
+currently active."
(interactive
- (if ledger-occur-mode
- (list nil)
- (list (read-string (concat "Regexp<" (ledger-occur-prompt) ">: ")
- nil 'ledger-occur-history (ledger-occur-prompt)))))
- (ledger-occur-mode regex (current-buffer)))
+ (list (read-regexp "Regexp" (ledger-occur-prompt) 'ledger-occur-history)))
+ (if (or (null regex)
+ (zerop (length regex))) ; empty regex, or already have narrowed, clear narrowing
+ (ledger-occur-mode -1)
+ (setq ledger-occur-current-regex regex)
+ (ledger-occur-mode 1)))
(defun ledger-occur-prompt ()
"Return the default value of the prompt.
Default value for prompt is a current word or active
region(selection), if its size is 1 line"
- (let ((prompt
- (if (and transient-mark-mode
- mark-active)
- (let ((pos1 (region-beginning))
- (pos2 (region-end)))
- ;; Check if the start and the of an active region is on
- ;; the same line
- (if (= (line-number-at-pos pos1)
- (line-number-at-pos pos2))
- (buffer-substring-no-properties pos1 pos2)))
- (current-word))))
- prompt))
+ (if (use-region-p)
+ (let ((pos1 (region-beginning))
+ (pos2 (region-end)))
+ ;; Check if the start and the of an active region is on
+ ;; the same line
+ (if (= (line-number-at-pos pos1)
+ (line-number-at-pos pos2))
+ (buffer-substring-no-properties pos1 pos2)))
+ (current-word)))
(defun ledger-occur-make-visible-overlay (beg end)
@@ -127,6 +118,7 @@ When REGEX is nil, unhide everything, and remove higlight"
Argument OVL-BOUNDS contains bounds for the transactions to be left visible."
(let* ((beg (caar ovl-bounds))
(end (cadar ovl-bounds)))
+ (ledger-occur-remove-overlays)
(ledger-occur-make-invisible-overlay (point-min) (1- beg))
(dolist (visible (cdr ovl-bounds))
(ledger-occur-make-visible-overlay beg end)
@@ -135,15 +127,6 @@ Argument OVL-BOUNDS contains bounds for the transactions to be left visible."
(setq end (cadr visible)))
(ledger-occur-make-invisible-overlay (1+ end) (point-max))))
-(defun ledger-occur-quit-buffer (buffer)
- "Quits hidings transaction in the given BUFFER.
-Used for coordinating `ledger-occur' with other buffers, like reconcile."
- (set-buffer buffer)
- (setq ledger-occur-mode nil)
- (force-mode-line-update)
- (ledger-occur-remove-overlays)
- (recenter))
-
(defun ledger-occur-remove-overlays ()
"Remove the transaction hiding overlays."
(interactive)
@@ -155,36 +138,30 @@ Used for coordinating `ledger-occur' with other buffers, like reconcile."
(save-excursion
(goto-char (point-min))
;; Set initial values for variables
- (let (curpoint
- endpoint
- (lines (list)))
+ (let (endpoint lines bounds)
;; Search loop
(while (not (eobp))
- (setq curpoint (point))
;; if something found
(when (setq endpoint (re-search-forward regex nil 'end))
- (save-excursion
- (let ((bounds (ledger-find-xact-extents (match-beginning 0))))
- (push bounds lines)
- (setq curpoint (cadr bounds)))) ;; move to the end of
- ;; the xact, no need to
- ;; search inside it more
- (goto-char curpoint))
- (forward-line 1))
- (setq lines (nreverse lines)))))
+ (setq bounds (ledger-navigate-find-element-extents endpoint))
+ (push bounds lines)
+ ;; move to the end of the xact, no need to search inside it more
+ (goto-char (cadr bounds))))
+ (nreverse lines))))
(defun ledger-occur-compress-matches (buffer-matches)
"identify sequential xacts to reduce number of overlays required"
- (let ((points (list))
- (current-beginning (caar buffer-matches))
- (current-end (cadar buffer-matches)))
- (dolist (match (cdr buffer-matches))
- (if (< (- (car match) current-end) 2)
- (setq current-end (cadr match))
- (push (list current-beginning current-end) points)
- (setq current-beginning (car match))
- (setq current-end (cadr match))))
- (nreverse (push (list current-beginning current-end) points))))
+ (if buffer-matches
+ (let ((points (list))
+ (current-beginning (caar buffer-matches))
+ (current-end (cadar buffer-matches)))
+ (dolist (match (cdr buffer-matches))
+ (if (< (- (car match) current-end) 2)
+ (setq current-end (cadr match))
+ (push (list current-beginning current-end) points)
+ (setq current-beginning (car match))
+ (setq current-end (cadr match))))
+ (nreverse (push (list current-beginning current-end) points)))))
(provide 'ledger-occur)
diff --git a/lisp/ledger-post.el b/lisp/ledger-post.el
index ac040bb2..e0c7aaee 100644
--- a/lisp/ledger-post.el
+++ b/lisp/ledger-post.el
@@ -1,6 +1,6 @@
;;; ledger-post.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
@@ -42,7 +42,7 @@
:group 'ledger-post)
(defcustom ledger-post-use-completion-engine :built-in
- "Which completion engine to use, :iswitchb or :ido chose those engines,
+ "Which completion engine to use, :iswitchb or :ido chose those engines.
:built-in uses built-in Ledger-mode completion"
:type '(radio (const :tag "built in completion" :built-in)
(const :tag "ido completion" :ido)
@@ -82,9 +82,8 @@ point at beginning of the commodity."
(- (or (match-end 4)
(match-end 3)) (point)))))
-
(defun ledger-next-account (&optional end)
- "Move point to the beginning of the next account, or status marker (!*), as long as it is not past END.
+ "Move to the beginning of the posting, or status marker, limit to END.
Return the column of the beginning of the account and leave point
at beginning of account"
(if (> end (point))
@@ -96,13 +95,13 @@ at beginning of account"
(current-column))))
(defun ledger-post-align-xact (pos)
- (interactive "d")
- (let ((bounds (ledger-find-xact-extents pos)))
+ "Align all the posting in the xact at POS."
+ (interactive "d")
+ (let ((bounds (ledger-navigate-find-xact-extents pos)))
(ledger-post-align-postings (car bounds) (cadr bounds))))
(defun ledger-post-align-postings (&optional beg end)
- "Align all accounts and amounts within region, if there is no
-region align the posting on the current line."
+ "Align all accounts and amounts between BEG and END, or the current line."
(interactive)
(save-excursion
@@ -110,62 +109,51 @@ region align the posting on the current line."
(not (use-region-p)))
(set-mark (point)))
- (let* ((inhibit-modification-hooks t)
- (mark-first (< (mark) (point)))
- (begin-region (if beg
- beg
- (if mark-first (mark) (point))))
- (end-region (if end
- end
- (if mark-first (point) (mark))))
- acct-start-column acct-end-column acct-adjust amt-width amt-adjust
- (lines-left 1))
- ;; Condition point and mark to the beginning and end of lines
- (goto-char end-region)
- (setq end-region (line-end-position))
- (goto-char begin-region)
- (goto-char
- (setq begin-region
- (line-beginning-position)))
-
- (untabify begin-region end-region)
-
- (goto-char end-region)
- (setq end-region (line-end-position))
- (goto-char begin-region)
- (goto-char
- (setq begin-region
- (line-beginning-position)))
-
- ;; This is the guts of the alignment loop
- (while (and (or (setq acct-start-column (ledger-next-account (line-end-position)))
- lines-left)
- (< (point) end-region))
- (when acct-start-column
- (setq acct-end-column (save-excursion
- (goto-char (match-end 2))
- (current-column)))
- (when (/= (setq acct-adjust (- ledger-post-account-alignment-column acct-start-column)) 0)
- (setq acct-end-column (+ acct-end-column acct-adjust)) ;;adjust the account ending column
- (if (> acct-adjust 0)
- (insert (make-string acct-adjust ? ))
- (delete-char acct-adjust)))
- (when (setq amt-width (ledger-next-amount (line-end-position)))
- (if (/= 0 (setq amt-adjust (- (if (> (- ledger-post-amount-alignment-column amt-width)
- (+ 2 acct-end-column))
- ledger-post-amount-alignment-column ;;we have room
- (+ acct-end-column 2 amt-width))
- amt-width
- (current-column))))
- (if (> amt-adjust 0)
- (insert (make-string amt-adjust ? ))
- (delete-char amt-adjust)))))
- (forward-line)
- (setq lines-left (not (eobp))))
+ (let ((inhibit-modification-hooks t)
+ (mark-first (< (mark) (point)))
+ acct-start-column acct-end-column acct-adjust amt-width amt-adjust
+ (lines-left 1))
+
+ (unless beg (setq beg (if mark-first (mark) (point))))
+ (unless end (setq end (if mark-first (mark) (point))))
+
+ ;; Extend region to whole lines
+ (let ((start-marker (set-marker (make-marker) (save-excursion
+ (goto-char beg)
+ (line-beginning-position))))
+ (end-marker (set-marker (make-marker) (save-excursion
+ (goto-char end)
+ (line-end-position)))))
+ (untabify start-marker end-marker)
+ (goto-char start-marker)
+
+ ;; This is the guts of the alignment loop
+ (while (and (or (setq acct-start-column (ledger-next-account (line-end-position)))
+ lines-left)
+ (< (point) end-marker))
+ (when acct-start-column
+ (setq acct-end-column (save-excursion
+ (goto-char (match-end 2))
+ (current-column)))
+ (when (/= (setq acct-adjust (- ledger-post-account-alignment-column acct-start-column)) 0)
+ (setq acct-end-column (+ acct-end-column acct-adjust)) ;;adjust the account ending column
+ (if (> acct-adjust 0)
+ (insert (make-string acct-adjust ? ))
+ (delete-char acct-adjust)))
+ (when (setq amt-width (ledger-next-amount (line-end-position)))
+ (if (/= 0 (setq amt-adjust (- (if (> (- ledger-post-amount-alignment-column amt-width)
+ (+ 2 acct-end-column))
+ ledger-post-amount-alignment-column ;;we have room
+ (+ acct-end-column 2 amt-width))
+ amt-width
+ (current-column))))
+ (if (> amt-adjust 0)
+ (insert (make-string amt-adjust ? ))
+ (delete-char amt-adjust)))))
+ (forward-line)
+ (setq lines-left (not (eobp)))))
(setq inhibit-modification-hooks nil))))
-
-
(defun ledger-post-edit-amount ()
"Call 'calc-mode' and push the amount in the posting to the top of stack."
(interactive)
@@ -186,24 +174,6 @@ region align the posting on the current line."
(insert " "))
(calc))))))
-(defun ledger-post-prev-xact ()
- "Move point to the previous transaction."
- (interactive)
- (backward-paragraph)
- (when (re-search-backward ledger-xact-line-regexp nil t)
- (goto-char (match-beginning 0))
- (re-search-forward ledger-post-line-regexp)
- (goto-char (match-end ledger-regex-post-line-group-account))))
-
-(defun ledger-post-next-xact ()
- "Move point to the next transaction."
- (interactive)
- (when (re-search-forward ledger-xact-line-regexp nil t)
- (goto-char (match-beginning 0))
- (re-search-forward ledger-post-line-regexp)
- (goto-char (match-end ledger-regex-post-line-group-account))))
-
-
(provide 'ledger-post)
diff --git a/lisp/ledger-reconcile.el b/lisp/ledger-reconcile.el
index 48d54eb0..80e27ae3 100644
--- a/lisp/ledger-reconcile.el
+++ b/lisp/ledger-reconcile.el
@@ -1,6 +1,6 @@
;;; ledger-reconcile.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
@@ -44,8 +44,7 @@
:group 'ledger-reconcile)
(defcustom ledger-narrow-on-reconcile t
- "If t, limit transactions shown in main buffer to those
-matching the reconcile regex."
+ "If t, limit transactions shown in main buffer to those matching the reconcile regex."
:type 'boolean
:group 'ledger-reconcile)
@@ -56,8 +55,7 @@ Then that transaction will be shown in its source buffer."
:group 'ledger-reconcile)
(defcustom ledger-reconcile-force-window-bottom nil
- "If t make the reconcile window appear along the bottom of the
-register window and resize."
+ "If t make the reconcile window appear along the bottom of the register window and resize."
:type 'boolean
:group 'ledger-reconcile)
@@ -68,25 +66,26 @@ reconcile-finish will mark all pending posting cleared."
:group 'ledger-reconcile)
(defcustom ledger-reconcile-default-date-format ledger-default-date-format
- "Default date format for the reconcile buffer"
+ "Default date format for the reconcile buffer."
:type 'string
:group 'ledger-reconcile)
(defcustom ledger-reconcile-target-prompt-string "Target amount for reconciliation "
- "Default prompt for recon target prompt"
+ "Default prompt for recon target prompt."
:type 'string
:group 'ledger-reconcile)
(defcustom ledger-reconcile-buffer-header "Reconciling account %s\n\n"
- "Default header string for the reconcile buffer. If non-nil,
- the name of the account being reconciled will be substituted
+ "Default header string for the reconcile buffer.
+
+If non-nil, the name of the account being reconciled will be substituted
into the '%s'. If nil, no header willbe displayed."
:type 'string
:group 'ledger-reconcile)
(defcustom ledger-reconcile-buffer-line-format "%(date)s %-4(code)s %-50(payee)s %-30(account)s %15(amount)s\n"
- "Format string for the ledger reconcile posting
-format. Available fields are date, status, code, payee, account,
+ "Format string for the ledger reconcile posting format.
+Available fields are date, status, code, payee, account,
amount. The format for each field is %WIDTH(FIELD), WIDTH can be
preced by a minus sign which mean to left justify and pad the
field."
@@ -94,8 +93,9 @@ field."
:group 'ledger-reconcile)
(defcustom ledger-reconcile-sort-key "(0)"
- "Default key for sorting reconcile buffer. Possible values are
-'(date)', '(amount)', '(payee)'. For no sorting, i.e. using
+ "Default key for sorting reconcile buffer.
+
+Possible values are '(date)', '(amount)', '(payee)'. For no sorting, i.e. using
ledger file order, use '(0)'."
:type 'string
:group 'ledger-reconcile)
@@ -106,7 +106,7 @@ ledger file order, use '(0)'."
:group 'ledger-reconcile)
(defun ledger-reconcile-get-cleared-or-pending-balance (buffer account)
- "Calculate the cleared or pending balance of the account."
+ "Use BUFFER to Calculate the cleared or pending balance of the ACCOUNT."
;; these vars are buffer local, need to hold them for use in the
;; temp buffer below
@@ -118,7 +118,7 @@ ledger file order, use '(0)'."
;; specify the individual fields in the command line.
(if (ledger-exec-ledger buffer (current-buffer)
"balance" "--limit" "cleared or pending" "--empty" "--collapse"
- "--format" "%(display_total)" account)
+ "--format" "%(scrub(display_total))" account)
(ledger-split-commodity-string
(buffer-substring-no-properties (point-min) (point-max))))))
@@ -157,7 +157,7 @@ And calculate the target-delta of the account being reconciled."
status)
(when (ledger-reconcile-get-buffer where)
(with-current-buffer (ledger-reconcile-get-buffer where)
- (ledger-goto-line (cdr where))
+ (ledger-navigate-to-line (cdr where))
(forward-char)
(setq status (ledger-toggle-current (if ledger-reconcile-toggle-to-pending
'pending
@@ -197,15 +197,16 @@ Return the number of uncleared xacts found."
(defun ledger-reconcile-refresh-after-save ()
"Refresh the recon-window after the ledger buffer is saved."
- (let ((curbuf (current-buffer))
+ (let ((curbufwin (get-buffer-window (current-buffer)))
(curpoint (point))
(recon-buf (get-buffer ledger-recon-buffer-name)))
(when (buffer-live-p recon-buf)
(with-current-buffer recon-buf
(ledger-reconcile-refresh)
(set-buffer-modified-p nil))
- (select-window (get-buffer-window curbuf))
- (goto-char curpoint))))
+ (when curbufwin
+ (select-window curbufwin)
+ (goto-char curpoint)))))
(defun ledger-reconcile-add ()
"Use ledger xact to add a new transaction."
@@ -220,7 +221,7 @@ Return the number of uncleared xacts found."
(let ((where (get-text-property (point) 'where)))
(when (ledger-reconcile-get-buffer where)
(with-current-buffer (ledger-reconcile-get-buffer where)
- (ledger-goto-line (cdr where))
+ (ledger-navigate-to-line (cdr where))
(ledger-delete-current-transaction (point)))
(let ((inhibit-read-only t))
(goto-char (line-beginning-position))
@@ -231,22 +232,22 @@ Return the number of uncleared xacts found."
(defun ledger-reconcile-visit (&optional come-back)
"Recenter ledger buffer on transaction and COME-BACK if non-nil."
(interactive)
- (progn
- (beginning-of-line)
- (let* ((where (get-text-property (1+ (point)) 'where))
- (target-buffer (if where
- (ledger-reconcile-get-buffer where)
- nil))
- (cur-win (get-buffer-window (get-buffer ledger-recon-buffer-name))))
- (when target-buffer
- (switch-to-buffer-other-window target-buffer)
- (ledger-goto-line (cdr where))
- (forward-char)
- (recenter)
- (ledger-highlight-xact-under-point)
- (forward-char -1)
- (if (and come-back cur-win)
- (select-window cur-win))))))
+ (beginning-of-line)
+ (let* ((where (get-text-property (1+ (point)) 'where))
+ (target-buffer (if where
+ (ledger-reconcile-get-buffer where)
+ nil))
+ (cur-win (get-buffer-window (get-buffer ledger-recon-buffer-name))))
+ (when target-buffer
+ (switch-to-buffer-other-window target-buffer)
+ (ledger-navigate-to-line (cdr where))
+ (forward-char)
+ (recenter)
+ (ledger-highlight-xact-under-point)
+ (forward-char -1)
+ (when (and come-back cur-win)
+ (select-window cur-win)
+ (get-buffer ledger-recon-buffer-name)))))
(defun ledger-reconcile-save ()
@@ -273,7 +274,7 @@ and exit reconcile mode"
(face (get-text-property (point) 'face)))
(if (eq face 'ledger-font-reconciler-pending-face)
(with-current-buffer (ledger-reconcile-get-buffer where)
- (ledger-goto-line (cdr where))
+ (ledger-navigate-to-line (cdr where))
(ledger-toggle-current 'cleared))))
(forward-line 1)))
(ledger-reconcile-save)
@@ -303,7 +304,7 @@ and exit reconcile mode"
(with-current-buffer buf
(remove-hook 'after-save-hook 'ledger-reconcile-refresh-after-save t)
(when ledger-narrow-on-reconcile
- (ledger-occur-quit-buffer buf)
+ (ledger-occur-mode -1)
(ledger-highlight-xact-under-point))))))
(defun ledger-marker-where-xact-is (emacs-xact posting)
@@ -319,7 +320,7 @@ POSTING is used in `ledger-clear-whole-transactions' is nil."
(nth 0 posting))))) ;; return line-no of posting
(defun ledger-reconcile-compile-format-string (fstr)
- "return a function that implements the format string in fstr"
+ "Return a function that implements the format string in FSTR."
(let (fields
(start 0))
(while (string-match "(\\(.*?\\))" fstr start)
@@ -332,6 +333,7 @@ POSTING is used in `ledger-clear-whole-transactions' is nil."
(defun ledger-reconcile-format-posting (beg where fmt date code status payee account amount)
+ "Format posting for the reconcile buffer."
(insert (funcall fmt date code status payee account amount))
; Set face depending on cleared status
@@ -348,6 +350,7 @@ POSTING is used in `ledger-clear-whole-transactions' is nil."
'where where))))
(defun ledger-reconcile-format-xact (xact fmt)
+ "Format XACT using FMT."
(let ((date-format (or (cdr (assoc "date-format" ledger-environment-alist))
ledger-default-date-format)))
(dolist (posting (nthcdr 5 xact))
@@ -364,7 +367,8 @@ POSTING is used in `ledger-clear-whole-transactions' is nil."
(nth 2 posting)))))) ; amount
(defun ledger-do-reconcile (&optional sort)
- "Return the number of uncleared transactions in the account and display them in the *Reconcile* buffer."
+ "SORT the uncleared transactions in the account and display them in the *Reconcile* buffer.
+Return a count of the uncleared transactions."
(let* ((buf ledger-buf)
(account ledger-acct)
(ledger-success nil)
@@ -399,9 +403,8 @@ POSTING is used in `ledger-clear-whole-transactions' is nil."
(length xacts)))
(defun ledger-reconcile-ensure-xacts-visible ()
- "Ensures that the last of the visible transactions in the
-ledger buffer is at the bottom of the main window. The key to
-this is to ensure the window is selected when the buffer point is
+ "Ensure the last of the visible transactions in the ledger buffer is at the bottom of the main window.
+The key to this is to ensure the window is selected when the buffer point is
moved and recentered. If they aren't strange things happen."
(let ((recon-window (get-buffer-window (get-buffer ledger-recon-buffer-name))))
@@ -436,6 +439,13 @@ moved and recentered. If they aren't strange things happen."
(set-window-buffer (split-window (get-buffer-window buf) nil nil) rbuf)
(pop-to-buffer rbuf)))
+(defun ledger-reconcile-check-valid-account (account)
+ "Check to see if ACCOUNT exists in the ledger file"
+ (if (> (length account) 0)
+ (save-excursion
+ (goto-char (point-min))
+ (search-forward account nil t))))
+
(defun ledger-reconcile ()
"Start reconciling, prompt for account."
(interactive)
@@ -443,37 +453,38 @@ moved and recentered. If they aren't strange things happen."
(buf (current-buffer))
(rbuf (get-buffer ledger-recon-buffer-name)))
- (add-hook 'after-save-hook 'ledger-reconcile-refresh-after-save nil t)
-
- (if rbuf ;; *Reconcile* already exists
- (with-current-buffer rbuf
- (set 'ledger-acct account) ;; already buffer local
- (when (not (eq buf rbuf))
- ;; called from some other ledger-mode buffer
- (ledger-reconcile-quit-cleanup)
- (setq ledger-buf buf)) ;; should already be buffer-local
-
- (unless (get-buffer-window rbuf)
- (ledger-reconcile-open-windows buf rbuf)))
-
- ;; no recon-buffer, starting from scratch.
-
- (with-current-buffer (setq rbuf
- (get-buffer-create ledger-recon-buffer-name))
- (ledger-reconcile-open-windows buf rbuf)
- (ledger-reconcile-mode)
- (make-local-variable 'ledger-target)
- (set (make-local-variable 'ledger-buf) buf)
- (set (make-local-variable 'ledger-acct) account)))
-
- ;; Narrow the ledger buffer
- (with-current-buffer rbuf
- (save-excursion
- (if ledger-narrow-on-reconcile
- (ledger-occur-mode account ledger-buf)))
- (if (> (ledger-reconcile-refresh) 0)
- (ledger-reconcile-change-target))
- (ledger-display-balance))))
+ (when (ledger-reconcile-check-valid-account account)
+ (add-hook 'after-save-hook 'ledger-reconcile-refresh-after-save nil t)
+
+ (if rbuf ;; *Reconcile* already exists
+ (with-current-buffer rbuf
+ (set 'ledger-acct account) ;; already buffer local
+ (when (not (eq buf rbuf))
+ ;; called from some other ledger-mode buffer
+ (ledger-reconcile-quit-cleanup)
+ (setq ledger-buf buf)) ;; should already be buffer-local
+
+ (unless (get-buffer-window rbuf)
+ (ledger-reconcile-open-windows buf rbuf)))
+
+ ;; no recon-buffer, starting from scratch.
+
+ (with-current-buffer (setq rbuf
+ (get-buffer-create ledger-recon-buffer-name))
+ (ledger-reconcile-open-windows buf rbuf)
+ (ledger-reconcile-mode)
+ (make-local-variable 'ledger-target)
+ (set (make-local-variable 'ledger-buf) buf)
+ (set (make-local-variable 'ledger-acct) account)))
+
+ ;; Narrow the ledger buffer
+ (with-current-buffer rbuf
+ (save-excursion
+ (if ledger-narrow-on-reconcile
+ (ledger-occur account)))
+ (if (> (ledger-reconcile-refresh) 0)
+ (ledger-reconcile-change-target))
+ (ledger-display-balance)))))
(defvar ledger-reconcile-mode-abbrev-table)
@@ -483,7 +494,8 @@ moved and recentered. If they aren't strange things happen."
(setq ledger-target (ledger-read-commodity-string ledger-reconcile-target-prompt-string)))
(defmacro ledger-reconcile-change-sort-key-and-refresh (sort-by)
- `(lambda ()
+ "Set the sort-key to SORT-BY."
+ `(lambda ()
(interactive)
(setq ledger-reconcile-sort-key ,sort-by)
diff --git a/lisp/ledger-regex.el b/lisp/ledger-regex.el
index bb080b94..41231845 100644
--- a/lisp/ledger-regex.el
+++ b/lisp/ledger-regex.el
@@ -1,6 +1,6 @@
;;; ledger-regex.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
@@ -26,10 +26,10 @@
(defconst ledger-amount-regex
(concat "\\( \\|\t\\| \t\\)[ \t]*-?"
- "\\([A-Z$€£_]+ *\\)?"
+ "\\([A-Z$€£₹_(]+ *\\)?"
"\\(-?[0-9,\\.]+?\\)"
- "\\(.[0-9]+\\)?"
- "\\( *[[:word:]€£_\"]+\\)?"
+ "\\(.[0-9)]+\\)?"
+ "\\( *[[:word:]€£₹_\"]+\\)?"
"\\([ \t]*[@={]@?[^\n;]+?\\)?"
"\\([ \t]+;.+?\\|[ \t]*\\)?$"))
@@ -329,7 +329,33 @@
ledger-iso-date-regexp
"\\([ *!]+\\)" ;; mark
"\\((.*)\\)?" ;; code
- "\\(.*\\)" ;; desc
+ "\\([[:word:] ]+\\)" ;; desc
"\\)"))
+(defconst ledger-xact-start-regex
+ (concat "^" ledger-iso-date-regexp ;; subexp 1
+ "\\(=" ledger-iso-date-regexp "\\)?"
+ ))
+
+(defconst ledger-xact-after-date-regex
+ (concat "\\([ \t]+[*!]\\)?" ;; mark, subexp 1
+ "\\([ \t]+(.*?)\\)?" ;; code, subexp 2
+ "\\([ \t]+[^;\n]+\\)" ;; desc, subexp 3
+ "\\(;[^\n]*\\)?" ;; comment, subexp 4
+ ))
+
+(defconst ledger-posting-regex
+ (concat "^[ \t]+ ?" ;; initial white space
+ "\\([*!]\\)? ?" ;; state, subexpr 1
+ "\\([[:print:]]+\\([ \t][ \t]\\)\\)" ;; account, subexpr 2
+ "\\([^;\n]*\\)" ;; amount, subexpr 4
+ "\\(.*\\)" ;; comment, subexpr 5
+ ))
+
+
+
+(defconst ledger-directive-start-regex
+ "[=~;#%|\\*[A-Za-z]")
+
+
(provide 'ledger-regex)
diff --git a/lisp/ledger-report.el b/lisp/ledger-report.el
index 85f75212..c477707f 100644
--- a/lisp/ledger-report.el
+++ b/lisp/ledger-report.el
@@ -1,6 +1,6 @@
;;; ledger-report.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
@@ -57,7 +57,8 @@ specifier."
'(("ledger-file" . ledger-report-ledger-file-format-specifier)
("payee" . ledger-report-payee-format-specifier)
("account" . ledger-report-account-format-specifier)
- ("value" . ledger-report-value-format-specifier))
+ ("tagname" . ledger-report-tagname-format-specifier)
+ ("tagvalue" . ledger-report-tagvalue-format-specifier))
"An alist mapping ledger report format specifiers to implementing functions.
The function is called with no parameters and expected to return the
@@ -70,6 +71,11 @@ text that should replace the format specifier."
:type 'boolean
:group 'ledger-report)
+(defcustom ledger-report-auto-refresh-sticky-cursor nil
+ "If t then try to place cursor at same relative position as it was before auto-refresh."
+ :type 'boolean
+ :group 'ledger-report)
+
(defvar ledger-report-buffer-name "*Ledger Report*")
(defvar ledger-report-name nil)
@@ -81,8 +87,16 @@ text that should replace the format specifier."
(defvar ledger-minibuffer-history nil)
(defvar ledger-report-mode-abbrev-table)
+(defvar ledger-report-is-reversed nil)
+(defvar ledger-report-cursor-line-number nil)
+
+(defun ledger-report-reverse-report ()
+ "Reverse the order of the report."
+ (interactive)
+ (ledger-report-reverse-lines)
+ (setq ledger-report-is-reversed (not ledger-report-is-reversed)))
+
(defun ledger-report-reverse-lines ()
- (interactive)
(goto-char (point-min))
(forward-paragraph)
(forward-line)
@@ -95,10 +109,11 @@ text that should replace the format specifier."
(define-key map [? ] 'scroll-up)
(define-key map [backspace] 'scroll-down)
(define-key map [?r] 'ledger-report-redo)
- (define-key map [(shift ?r)] 'ledger-report-reverse-lines)
+ (define-key map [(shift ?r)] 'ledger-report-reverse-report)
(define-key map [?s] 'ledger-report-save)
(define-key map [?k] 'ledger-report-kill)
- (define-key map [?e] 'ledger-report-edit)
+ (define-key map [?e] 'ledger-report-edit-report)
+ (define-key map [( shift ?e)] 'ledger-report-edit-reports)
(define-key map [?q] 'ledger-report-quit)
(define-key map [?g] 'ledger-report-redo)
(define-key map [(control ?c) (control ?l) (control ?r)]
@@ -117,11 +132,11 @@ text that should replace the format specifier."
"Ledger report menu"
'("Reports"
["Save Report" ledger-report-save]
- ["Edit Report" ledger-report-edit]
+ ["Edit Current Report" ledger-report-edit-report]
+ ["Edit All Reports" ledger-report-edit-reports]
["Re-run Report" ledger-report-redo]
- ["Kill Report" ledger-report-kill]
"---"
- ["Reverse report order" ledger-report-reverse-lines]
+ ["Reverse report order" ledger-report-reverse-report]
"---"
["Scroll Up" scroll-up]
["Visit Source" ledger-report-visit-source]
@@ -133,11 +148,17 @@ text that should replace the format specifier."
(define-derived-mode ledger-report-mode text-mode "Ledger-Report"
"A mode for viewing ledger reports.")
-(defun ledger-report-value-format-specifier ()
+(defun ledger-report-tagname-format-specifier ()
"Return a valid meta-data tag name"
;; It is intended completion should be available on existing account
;; names, but it remains to be implemented.
- (ledger-read-string-with-default "Value: " nil))
+ (ledger-read-string-with-default "Tag Name: " nil))
+
+(defun ledger-report-tagvalue-format-specifier ()
+ "Return a valid meta-data tag name"
+ ;; It is intended completion should be available on existing account
+ ;; names, but it remains to be implemented.
+ (ledger-read-string-with-default "Tag Value: " nil))
(defun ledger-report-read-name ()
"Read the name of a ledger report to use, with completion.
@@ -182,13 +203,14 @@ used to generate the buffer, navigating the buffer, etc."
(set (make-local-variable 'ledger-buf) buf)
(set (make-local-variable 'ledger-report-name) report-name)
(set (make-local-variable 'ledger-original-window-cfg) wcfg)
+ (set (make-local-variable 'ledger-report-is-reversed) nil)
(ledger-do-report (ledger-report-cmd report-name edit))
(shrink-window-if-larger-than-buffer)
(set-buffer-modified-p nil)
(setq buffer-read-only t)
(message "q to quit; r to redo; e to edit; k to kill; s to save; SPC and DEL to scroll"))))
-(defun string-empty-p (s)
+(defun ledger-report-string-empty-p (s)
"Check S for the empty string."
(string-equal "" s))
@@ -197,7 +219,7 @@ used to generate the buffer, navigating the buffer, etc."
If name exists, returns the object naming the report,
otherwise returns nil."
- (unless (string-empty-p name)
+ (unless (ledger-report-string-empty-p name)
(car (assoc name ledger-reports))))
(defun ledger-reports-add (name cmd)
@@ -288,7 +310,7 @@ Optional EDIT the command."
(setq ledger-report-saved nil)) ;; this is a new report, or edited report
(setq report-cmd (ledger-report-expand-format-specifiers report-cmd))
(set (make-local-variable 'ledger-report-cmd) report-cmd)
- (or (string-empty-p report-name)
+ (or (ledger-report-string-empty-p report-name)
(ledger-report-name-exists report-name)
(progn
(ledger-reports-add report-name report-cmd)
@@ -325,7 +347,7 @@ Optional EDIT the command."
(save-excursion
(find-file file)
(widen)
- (ledger-goto-line line)
+ (ledger-navigate-to-line line)
(point-marker))))))
(add-text-properties (line-beginning-position) (line-end-position)
(list 'face 'ledger-font-report-clickable-face))
@@ -367,16 +389,20 @@ Optional EDIT the command."
(interactive)
(let ((cur-buf (current-buffer)))
(if (and ledger-report-auto-refresh
- (string= (format-mode-line 'mode-name) "Ledger")
- (get-buffer ledger-report-buffer-name))
+ (or (string= (format-mode-line 'mode-name) "Ledger")
+ (string= (format-mode-line 'mode-name) "Ledger-Report"))
+ (get-buffer ledger-report-buffer-name))
(progn
(pop-to-buffer (get-buffer ledger-report-buffer-name))
(shrink-window-if-larger-than-buffer)
(setq buffer-read-only nil)
+ (setq ledger-report-cursor-line-number (line-number-at-pos))
(erase-buffer)
(ledger-do-report ledger-report-cmd)
(setq buffer-read-only nil)
+ (if ledger-report-is-reversed (ledger-report-reverse-lines))
+ (if ledger-report-auto-refresh-sticky-cursor (forward-line (- ledger-report-cursor-line-number 5)))
(pop-to-buffer cur-buf)))))
(defun ledger-report-quit ()
@@ -386,21 +412,21 @@ Optional EDIT the command."
(set-window-configuration ledger-original-window-cfg)
(kill-buffer (get-buffer ledger-report-buffer-name)))
-(defun ledger-report-kill ()
- "Kill the ledger report buffer."
- (interactive)
- (ledger-report-quit)
- (kill-buffer (get-buffer ledger-report-buffer-name)))
-
-(defun ledger-report-edit ()
+(defun ledger-report-edit-reports ()
"Edit the defined ledger reports."
(interactive)
(customize-variable 'ledger-reports))
+(defun ledger-report-edit-report ()
+ (interactive)
+ "Edit the current report command in the mini buffer and re-run the report"
+ (setq ledger-report-cmd (ledger-report-read-command ledger-report-cmd))
+ (ledger-report-redo))
+
(defun ledger-report-read-new-name ()
"Read the name for a new report from the minibuffer."
(let ((name ""))
- (while (string-empty-p name)
+ (while (ledger-report-string-empty-p name)
(setq name (read-from-minibuffer "Report name: " nil nil nil
'ledger-report-name-prompt-history)))
name))
@@ -410,7 +436,7 @@ Optional EDIT the command."
(interactive)
(ledger-report-goto)
(let (existing-name)
- (when (string-empty-p ledger-report-name)
+ (when (ledger-report-string-empty-p ledger-report-name)
(setq ledger-report-name (ledger-report-read-new-name)))
(if (setq existing-name (ledger-report-name-exists ledger-report-name))
diff --git a/lisp/ledger-schedule.el b/lisp/ledger-schedule.el
index 8e2ab1f6..d66fdbab 100644
--- a/lisp/ledger-schedule.el
+++ b/lisp/ledger-schedule.el
@@ -22,7 +22,7 @@
;;; Commentary:
;;
;; This module provides for automatically adding transactions to a
-;; ledger buffer on a periodic basis. Recurrence expressions are
+;; ledger buffer on a periodic basis. Recurrence expressions are
;; inspired by Martin Fowler's "Recurring Events for Calendars",
;; martinfowler.com/apsupp/recurring.pdf
@@ -31,13 +31,16 @@
;; function without have to use funcall.
(require 'ledger-init)
+(require 'cl)
+
+;;; Code:
(defgroup ledger-schedule nil
"Support for automatically recommendation transactions."
:group 'ledger)
(defcustom ledger-schedule-buffer-name "*Ledger Schedule*"
- "Name for the schedule buffer"
+ "Name for the schedule buffer."
:type 'string
:group 'ledger-schedule)
@@ -47,7 +50,7 @@
:group 'ledger-schedule)
(defcustom ledger-schedule-look-forward 14
- "Number of days auto look forward to recommend transactions"
+ "Number of days auto look forward to recommend transactions."
:type 'integer
:group 'ledger-schedule)
@@ -56,28 +59,40 @@
:type 'file
:group 'ledger-schedule)
-(defvar ledger-schedule-available nil)
+(defcustom ledger-schedule-week-days '(("Mo" 1)
+ ("Tu" 2)
+ ("We" 3)
+ ("Th" 4)
+ ("Fr" 5)
+ ("Sa" 6)
+ ("Su" 7))
+ "List of weekday abbreviations. There must be exactly seven
+entries each with a two character abbreviation for a day and the
+number of that day in the week. "
+ :type '(alist :value-type (group integer))
+ :group 'ledger-schedule)
(defsubst between (val low high)
- (and (>= val low) (<= val high)))
-
-(defun ledger-schedule-check-available ()
- (setq ledger-schedule-available (and ledger-schedule-file
- (file-exists-p ledger-schedule-file))))
+ "Return TRUE if VAL > LOW and < HIGH."
+ (and (>= val low) (<= val high)))
(defun ledger-schedule-days-in-month (month year)
"Return number of days in the MONTH, MONTH is from 1 to 12.
-If year is nil, assume it is not a leap year"
+If YEAR is nil, assume it is not a leap year"
(if (between month 1 12)
(if (and year (date-leap-year-p year) (= 2 month))
29
(nth (1- month) '(31 28 31 30 31 30 31 31 30 31 30 31)))
(error "Month out of range, MONTH=%S" month)))
+(defun ledger-schedule-encode-day-of-week (day-string)
+ "Return the numerical day of week corresponding to DAY-STRING."
+ (cadr (assoc day-string ledger-schedule-week-days)))
+
;; Macros to handle date expressions
(defun ledger-schedule-constrain-day-in-month (count day-of-week)
- "Return a form that evaluates DATE that returns true for the COUNT DAY-OF-WEEK.
+ "Return a form that returns TRUE for the the COUNT DAY-OF-WEEK.
For example, return true if date is the 3rd Thursday of the
month. Negative COUNT starts from the end of the month. (EQ
COUNT 0) means EVERY day-of-week (eg. every Saturday)"
@@ -109,11 +124,11 @@ COUNT 0) means EVERY day-of-week (eg. every Saturday)"
day-of-week)))
(defun ledger-schedule-constrain-every-count-day (day-of-week skip start-date)
- "Return a form that is true for every DAY skipping SKIP, starting on START.
+ "Return a form that is true for every DAY-OF-WEEK skipping SKIP, starting on START-DATE.
For example every second Friday, regardless of month."
- (let ((start-day (nth 6 (decode-time (eval start-date)))))
+ (let ((start-day (nth 6 (decode-time start-date))))
(if (eq start-day day-of-week) ;; good, can proceed
- `(zerop (mod (- (time-to-days date) ,(time-to-days (eval start-date))) ,(* skip 7)))
+ `(zerop (mod (- (time-to-days date) ,(time-to-days start-date)) ,(* skip 7)))
(error "START-DATE day of week doesn't match DAY-OF-WEEK"))))
(defun ledger-schedule-constrain-date-range (month1 day1 month2 day2)
@@ -130,12 +145,10 @@ For example every second Friday, regardless of month."
(< ,target-day ,day2))))))
-(defun ledger-schedule-is-holiday (date)
- "Return true if DATE is a holiday.")
(defun ledger-schedule-scan-transactions (schedule-file)
- "Scans AUTO_FILE and returns a list of transactions with date predicates.
-The car of each item is a fuction of date that returns true if
+ "Scan SCHEDULE-FILE and return a list of transactions with date predicates.
+The car of each item is a function of date that returns true if
the transaction should be logged for that day."
(interactive "fFile name: ")
(let ((xact-list (list)))
@@ -146,67 +159,27 @@ the transaction should be logged for that day."
(let ((date-descriptor "")
(transaction nil)
(xact-start (match-end 0)))
- (setq date-descriptors
+ (setq date-descriptor
(ledger-schedule-read-descriptor-tree
(buffer-substring-no-properties
(match-beginning 0)
(match-end 0))))
(forward-paragraph)
- (setq transaction (list date-descriptors
+ (setq transaction (list date-descriptor
(buffer-substring-no-properties
xact-start
(point))))
(setq xact-list (cons transaction xact-list))))
xact-list)))
-(defun ledger-schedule-replace-brackets ()
- "Replace all brackets with parens"
- (goto-char (point-min))
- (while (search-forward "]" nil t)
- (replace-match ")" nil t))
- (goto-char (point-min))
- (while (search-forward "[" nil t)
- (replace-match "(" nil t)))
-
-(defvar ledger-schedule-descriptor-regex
- (concat "\\(20[0-9][0-9]\\|[\*]\\)[/\\-]" ;; Year slot
- "\\([\*EO]\\|[01][0-9]\\)[/\\-]" ;; Month slot
- "\\([\*]\\|\\([0-3][0-9]\\)\\|"
- "\\([0-5]"
- "\\(\\(Su\\)\\|"
- "\\(Mo\\)\\|"
- "\\(Tu\\)\\|"
- "\\(We\\)\\|"
- "\\(Th\\)\\|"
- "\\(Fr\\)\\|"
- "\\(Sa\\)\\)\\)\\)"))
-
(defun ledger-schedule-read-descriptor-tree (descriptor-string)
- "Take a date DESCRIPTOR-STRING and return a function of date that
-returns true if the date meets the requirements"
- (with-temp-buffer
- ;; copy the descriptor string into a temp buffer for manipulation
- (let (pos)
- ;; Replace brackets with parens
- (insert descriptor-string)
- (ledger-schedule-replace-brackets)
-
- (goto-char (point-max))
- ;; double quote all the descriptors for string processing later
- (while (re-search-backward ledger-schedule-descriptor-regex nil t) ;; Day slot
- (goto-char
- (match-end 0))
- (insert ?\")
- (goto-char (match-beginning 0))
- (insert "\"" )))
-
- ;; read the descriptor string into a lisp object the transform the
- ;; string descriptor into useable things
- (ledger-schedule-transform-auto-tree
- (read (buffer-substring-no-properties (point-min) (point-max))))))
+ "Read DESCRIPTOR-STRING and return a form that evaluates dates."
+ (ledger-schedule-transform-auto-tree
+ (split-string
+ (substring descriptor-string 1 (string-match "]" descriptor-string)) " ")))
(defun ledger-schedule-transform-auto-tree (descriptor-string-list)
- "Takes a lisp list of date descriptor strings, TREE, and returns a string with a lambda function of date."
+ "Take DESCRIPTOR-STRING-LIST, and return a string with a lambda function of date."
;; use funcall to use the lambda function spit out here
(if (consp descriptor-string-list)
(let (result)
@@ -221,70 +194,92 @@ returns true if the date meets the requirements"
(push (ledger-schedule-compile-constraints newcar) result)) )
(setq descriptor-string-list (cdr descriptor-string-list)))
- ;; tie up all the clauses in a big or and lambda, and return
+ ;; tie up all the clauses in a big or lambda, and return
;; the lambda function as list to be executed by funcall
`(lambda (date)
,(nconc (list 'or) (nreverse result) descriptor-string-list)))))
(defun ledger-schedule-compile-constraints (descriptor-string)
- "Return a list with the year, month and day fields split"
- (let ((fields (split-string descriptor-string "[/\\-]" t))
- constrain-year constrain-month constrain-day)
- (setq constrain-year (ledger-schedule-constrain-year (nth 0 fields)))
- (setq constrain-month (ledger-schedule-constrain-month (nth 1 fields)))
- (setq constrain-day (ledger-schedule-constrain-day (nth 2 fields)))
-
- (list 'and constrain-year constrain-month constrain-day)))
-
-(defun ledger-schedule-constrain-year (str)
- (let ((year-match t))
- (cond ((string= str "*")
- year-match)
- ((/= 0 (setq year-match (string-to-number str)))
- `(eq (nth 5 (decode-time date)) ,year-match))
- (t
- (error "Improperly specified year constraint: %s" str)))))
-
-(defun ledger-schedule-constrain-month (str)
-
- (let ((month-match t))
- (cond ((string= str "*")
- month-match) ;; always match
- ((/= 0 (setq month-match (string-to-number str)))
- (if (between month-match 1 12) ;; no month specified, assume 31 days.
- `(eq (nth 4 (decode-time date)) ,month-match)
- (error "ledger-schedule-constrain-numerical-month: month out of range %S" month-match)))
- (t
- (error "Improperly specified month constraint: %s" str)))))
-
-(defun ledger-schedule-constrain-day (str)
- (let ((day-match t))
- (cond ((string= str "*")
- t)
- ((/= 0 (setq day-match (string-to-number str)))
- `(eq (nth 3 (decode-time date)) ,day-match))
- (t
- (error "Improperly specified day constraint: %s" str)))))
-
-(defun ledger-schedule-parse-date-descriptor (descriptor)
- "Parse the date descriptor, return the evaluator"
- (ledger-schedule-compile-constraints descriptor))
+ "Return a list with the year, month and day fields split."
+ (let ((fields (split-string descriptor-string "[/\\-]" t)))
+ (if (string-match "[A-Za-z]" descriptor-string)
+ (ledger-schedule-constrain-day (nth 0 fields) (nth 1 fields) (nth 2 fields))
+ (list 'and
+ (ledger-schedule-constrain-day (nth 0 fields) (nth 1 fields) (nth 2 fields))
+ (ledger-schedule-constrain-year (nth 0 fields) (nth 1 fields) (nth 2 fields))
+ (ledger-schedule-constrain-month (nth 0 fields) (nth 1 fields) (nth 2 fields))))))
+
+(defun ledger-schedule-constrain-year (year-desc month-desc day-desc)
+ "Return a form that constrains the year.
+
+YEAR-DESC, MONT-DESC, and DAY-DESC are the string portions of the
+date descriptor."
+ (cond ((string= year-desc "*") t)
+ ((/= 0 (string-to-number year-desc))
+ `(memq (nth 5 (decode-time date)) ',(mapcar 'string-to-number (split-string year-desc ","))))
+ (t
+ (error "Improperly specified year constraint: %s %s %s" year-desc month-desc day-desc))))
+
+(defun ledger-schedule-constrain-month (year-desc month-desc day-desc)
+ "Return a form that constrains the month.
+
+YEAR-DESC, MONT-DESC, and DAY-DESC are the string portions of the
+date descriptor."
+ (cond ((string= month-desc "*")
+ t) ;; always match
+ ((string= month-desc "E") ;; Even
+ `(evenp (nth 4 (decode-time date))))
+ ((string= month-desc "O") ;; Odd
+ `(oddp (nth 4 (decode-time date))))
+ ((/= 0 (string-to-number month-desc)) ;; Starts with number
+ `(memq (nth 4 (decode-time date)) ',(mapcar 'string-to-number (split-string month-desc ","))))
+ (t
+ (error "Improperly specified month constraint: %s %s %s" year-desc month-desc day-desc))))
+
+(defun ledger-schedule-constrain-day (year-desc month-desc day-desc)
+ "Return a form that constrains the day.
+
+YEAR-DESC, MONT-DESC, and DAY-DESC are the string portions of the
+date descriptor."
+ (cond ((string= day-desc "*")
+ t)
+ ((string-match "[A-Za-z]" day-desc) ;; There is something other than digits and commas
+ (ledger-schedule-parse-complex-date year-desc month-desc day-desc))
+ ((/= 0 (string-to-number day-desc))
+ `(memq (nth 3 (decode-time date)) ',(mapcar 'string-to-number (split-string day-desc ","))))
+ (t
+ (error "Improperly specified day constraint: %s %s %s" year-desc month-desc day-desc))))
+
+
+
+(defun ledger-schedule-parse-complex-date (year-desc month-desc day-desc)
+ "Parse day descriptors that have repeats."
+ (let ((years (mapcar 'string-to-number (split-string year-desc ",")))
+ (months (mapcar 'string-to-number (split-string month-desc ",")))
+ (day-parts (split-string day-desc "+"))
+ (every-nth (string-match "+" day-desc)))
+ (if every-nth
+ (let ((base-day (string-to-number (car day-parts)))
+ (increment (string-to-number (substring (cadr day-parts) 0
+ (string-match "[A-Za-z]" (cadr day-parts)))))
+ (day-of-week (ledger-schedule-encode-day-of-week
+ (substring (cadr day-parts) (string-match "[A-Za-z]" (cadr day-parts))))))
+ (ledger-schedule-constrain-every-count-day day-of-week increment (encode-time 0 0 0 base-day (car months) (car years))))
+ (let ((count (string-to-number (substring (car day-parts) 0 1)))
+ (day-of-week (ledger-schedule-encode-day-of-week
+ (substring (car day-parts) (string-match "[A-Za-z]" (car day-parts))))))
+ (ledger-schedule-constrain-day-in-month count day-of-week)))))
(defun ledger-schedule-list-upcoming-xacts (candidate-items early horizon)
- "Search CANDIDATE-ITEMS for xacts that occur within the period today - EARLY to today + HORIZON"
- (let ((start-date (time-subtract (current-time) (days-to-time early)))
- test-date items)
- (loop for day from 0 to (+ early horizon) by 1 do
- (setq test-date (time-add start-date (days-to-time day)))
- (dolist (candidate candidate-items items)
- (if (funcall (car candidate) test-date)
- (setq items (append items (list (list test-date (cadr candidate))))))))
- items))
-
-(defun ledger-schedule-already-entered (candidate buffer)
- (let ((target-date (format-time-string date-format (car candidate)))
- (target-payee (cadr candidate)))
- nil))
+ "Search CANDIDATE-ITEMS for xacts that occur within the period today - EARLY to today + HORIZON."
+ (let ((start-date (time-subtract (current-time) (days-to-time early)))
+ test-date items)
+ (loop for day from 0 to (+ early horizon) by 1 do
+ (setq test-date (time-add start-date (days-to-time day)))
+ (dolist (candidate candidate-items items)
+ (if (funcall (car candidate) test-date)
+ (setq items (append items (list (list test-date (cadr candidate))))))))
+ items))
(defun ledger-schedule-create-auto-buffer (candidate-items early horizon ledger-buf)
"Format CANDIDATE-ITEMS for display."
@@ -295,13 +290,12 @@ returns true if the date meets the requirements"
(with-current-buffer schedule-buf
(erase-buffer)
(dolist (candidate candidates)
- (if (not (ledger-schedule-already-entered candidate ledger-buf))
- (insert (format-time-string date-format (car candidate) ) " " (cadr candidate) "\n")))
+ (insert (format-time-string date-format (car candidate) ) " " (cadr candidate) "\n"))
(ledger-mode))
(length candidates)))
(defun ledger-schedule-upcoming (file look-backward look-forward)
- "Generate upcoming transaction
+ "Generate upcoming transactions.
FILE is the file containing the scheduled transaction,
default to `ledger-schedule-file'.
@@ -316,12 +310,16 @@ Use a prefix arg to change the default value"
(read-number "Look backward: " ledger-schedule-look-backward)
(read-number "Look forward: " ledger-schedule-look-forward))
(list ledger-schedule-file ledger-schedule-look-backward ledger-schedule-look-forward)))
- (ledger-schedule-create-auto-buffer
- (ledger-schedule-scan-transactions file)
- look-backward
- look-forward
- (current-buffer))
- (pop-to-buffer ledger-schedule-buffer-name))
+ (if (and file
+ (file-exists-p file))
+ (progn
+ (ledger-schedule-create-auto-buffer
+ (ledger-schedule-scan-transactions file)
+ look-backward
+ look-forward
+ (current-buffer))
+ (pop-to-buffer ledger-schedule-buffer-name))
+ (error "Could not find ledger schedule file at %s" file)))
(provide 'ledger-schedule)
diff --git a/lisp/ledger-sort.el b/lisp/ledger-sort.el
index 80472a35..870e298c 100644
--- a/lisp/ledger-sort.el
+++ b/lisp/ledger-sort.el
@@ -1,6 +1,6 @@
;;; ledger-xact.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
@@ -26,25 +26,19 @@
;;; Code:
-(defun ledger-next-record-function ()
- "Move point to next transaction."
- (if (re-search-forward ledger-payee-any-status-regex nil t)
- (goto-char (match-beginning 0))
- (goto-char (point-max))))
-
-(defun ledger-end-record-function ()
- "Move point to end of transaction."
- (forward-paragraph))
(defun ledger-sort-find-start ()
+ "Find the beginning of a sort region"
(if (re-search-forward ";.*Ledger-mode:.*Start sort" nil t)
(match-end 0)))
(defun ledger-sort-find-end ()
+ "Find the end of a sort region"
(if (re-search-forward ";.*Ledger-mode:.*End sort" nil t)
(match-end 0)))
(defun ledger-sort-insert-start-mark ()
+ "Insert a marker to start a sort region"
(interactive)
(save-excursion
(goto-char (point-min))
@@ -54,6 +48,7 @@
(insert "\n; Ledger-mode: Start sort\n\n"))
(defun ledger-sort-insert-end-mark ()
+ "Insert a marker to end a sort region"
(interactive)
(save-excursion
(goto-char (point-min))
@@ -69,11 +64,11 @@
(defun ledger-sort-region (beg end)
"Sort the region from BEG to END in chronological order."
(interactive "r") ;; load beg and end from point and mark
- ;; automagically
+ ;; automagically
(let ((new-beg beg)
(new-end end)
point-delta
- (bounds (ledger-find-xact-extents (point)))
+ (bounds (ledger-navigate-find-xact-extents (point)))
target-xact)
(setq point-delta (- (point) (car bounds)))
@@ -82,12 +77,14 @@
(save-excursion
(save-restriction
(goto-char beg)
- (ledger-next-record-function) ;; make sure point is at the
- ;; beginning of a xact
+ ;; make sure point is at the beginning of a xact
+ (ledger-navigate-next-xact)
+ (unless (looking-at ledger-payee-any-status-regex)
+ (ledger-navigate-next-xact))
(setq new-beg (point))
(goto-char end)
- (ledger-next-record-function) ;; make sure end of region is at
- ;; the beginning of next record
+ (ledger-navigate-next-xact)
+ ;; make sure end of region is at the beginning of next record
;; after the region
(setq new-end (point))
(narrow-to-region new-beg new-end)
@@ -96,8 +93,8 @@
(let ((inhibit-field-text-motion t))
(sort-subr
nil
- 'ledger-next-record-function
- 'ledger-end-record-function
+ 'ledger-navigate-next-xact
+ 'ledger-navigate-end-of-xact
'ledger-sort-startkey))))
(goto-char (point-min))
diff --git a/lisp/ledger-state.el b/lisp/ledger-state.el
index 989e6d33..47805f15 100644
--- a/lisp/ledger-state.el
+++ b/lisp/ledger-state.el
@@ -1,6 +1,6 @@
;;; ledger-state.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
@@ -65,6 +65,16 @@
((eql state-char ?\;) 'comment)
(t nil)))
+
+(defun ledger-state-from-string (state-string)
+ "Get state from STATE-CHAR."
+ (when state-string
+ (cond
+ ((string-match "\\!" state-string) 'pending)
+ ((string-match "\\*" state-string) 'cleared)
+ ((string-match ";" state-string) 'comment)
+ (t nil))))
+
(defun ledger-toggle-current-posting (&optional style)
"Toggle the cleared status of the transaction under point.
Optional argument STYLE may be `pending' or `cleared', depending
@@ -77,7 +87,7 @@ achieved more certainly by passing the xact to ledger for
formatting, but doing so causes inline math expressions to be
dropped."
(interactive)
- (let ((bounds (ledger-find-xact-extents (point)))
+ (let ((bounds (ledger-navigate-find-xact-extents (point)))
new-status cur-status)
;; Uncompact the xact, to make it easier to toggle the
;; transaction
diff --git a/lisp/ledger-test.el b/lisp/ledger-test.el
index 5f9f02fa..da120f63 100644
--- a/lisp/ledger-test.el
+++ b/lisp/ledger-test.el
@@ -1,6 +1,6 @@
;;; ledger-test.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
@@ -19,6 +19,16 @@
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
;; MA 02110-1301 USA.
+;;; Commentary:
+
+;;; Code:
+
+(declare-function ledger-mode "ledger-mode") ; TODO: fix this cyclic dependency
+(declare-function org-narrow-to-subtree "org")
+(declare-function org-entry-get "org")
+(declare-function outline-back-to-heading "outline")
+(declare-function outline-next-heading "outline")
+
(defgroup ledger-test nil
"Definitions for the Ledger testing framework"
:group 'ledger)
@@ -125,3 +135,5 @@
(cd prev-directory)))))))
(provide 'ledger-test)
+
+;;; ledger-test.el ends here
diff --git a/lisp/ledger-texi.el b/lisp/ledger-texi.el
index 746051bf..afaf0df7 100644
--- a/lisp/ledger-texi.el
+++ b/lisp/ledger-texi.el
@@ -1,6 +1,6 @@
;;; ledger-texi.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
diff --git a/lisp/ledger-xact.el b/lisp/ledger-xact.el
index e747b6b2..0eb9386a 100644
--- a/lisp/ledger-xact.el
+++ b/lisp/ledger-xact.el
@@ -1,6 +1,6 @@
;;; ledger-xact.el --- Helper code for use with the "ledger" command-line tool
-;; Copyright (C) 2003-2014 John Wiegley (johnw AT gnu DOT org)
+;; Copyright (C) 2003-2015 John Wiegley (johnw AT gnu DOT org)
;; This file is not part of GNU Emacs.
@@ -25,6 +25,11 @@
;;; Code:
+(require 'eshell)
+(require 'ledger-regex)
+(require 'ledger-navigate)
+;; TODO: This file depends on code in ledger-mode.el, which depends on this.
+
(defcustom ledger-highlight-xact-under-point t
"If t highlight xact under point."
:type 'boolean
@@ -39,26 +44,10 @@
(defvar ledger-xact-highlight-overlay (list))
(make-variable-buffer-local 'ledger-xact-highlight-overlay)
-(defun ledger-find-xact-extents (pos)
- "Return point for beginning of xact and and of xact containing position.
-Requires empty line separating xacts. Argument POS is a location
-within the transaction."
- (interactive "d")
- (save-excursion
- (goto-char pos)
- (list (progn
- (backward-paragraph)
- (if (/= (point) (point-min))
- (forward-line))
- (line-beginning-position))
- (progn
- (forward-paragraph)
- (line-beginning-position)))))
-
(defun ledger-highlight-xact-under-point ()
"Move the highlight overlay to the current transaction."
(if ledger-highlight-xact-under-point
- (let ((exts (ledger-find-xact-extents (point)))
+ (let ((exts (ledger-navigate-find-element-extents (point)))
(ovl ledger-xact-highlight-overlay))
(if (not ledger-xact-highlight-overlay)
(setq ovl
@@ -68,7 +57,7 @@ within the transaction."
(current-buffer) t nil)))
(move-overlay ovl (car exts) (cadr exts)))
(overlay-put ovl 'face 'ledger-font-xact-highlight-face)
- (overlay-put ovl 'priority 100))))
+ (overlay-put ovl 'priority '(nil . 99)))))
(defun ledger-xact-payee ()
"Return the payee of the transaction containing point or nil."
@@ -98,7 +87,7 @@ MOMENT is an encoded date"
(if (ledger-time-less-p moment date)
(throw 'found t))))))
(when (and (eobp) last-xact-start)
- (let ((end (cadr (ledger-find-xact-extents last-xact-start))))
+ (let ((end (cadr (ledger-navigate-find-xact-extents last-xact-start))))
(goto-char end)
(if (eobp)
(insert "\n")
@@ -129,11 +118,6 @@ MOMENT is an encoded date"
mark desc)))))
(forward-line))))
-(defun ledger-goto-line (line-number)
- "Rapidly move point to line LINE-NUMBER."
- (goto-char (point-min))
- (forward-line (1- line-number)))
-
(defun ledger-year-and-month ()
(let ((sep (if ledger-use-iso-dates
"-"
@@ -145,7 +129,7 @@ MOMENT is an encoded date"
(interactive (list
(ledger-read-date "Copy to date: ")))
(let* ((here (point))
- (extents (ledger-find-xact-extents (point)))
+ (extents (ledger-navigate-find-xact-extents (point)))
(transaction (buffer-substring-no-properties (car extents) (cadr extents)))
encoded-date)
(if (string-match ledger-iso-date-regexp date)
@@ -155,7 +139,7 @@ MOMENT is an encoded date"
(string-to-number (match-string 2 date)))))
(ledger-xact-find-slot encoded-date)
(insert transaction "\n")
- (backward-paragraph 2)
+ (ledger-navigate-beginning-of-xact)
(re-search-forward ledger-iso-date-regexp)
(replace-match date)
(ledger-next-amount)
@@ -163,9 +147,9 @@ MOMENT is an encoded date"
(goto-char (match-beginning 0)))))
(defun ledger-delete-current-transaction (pos)
- "Delete the transaction surrounging point."
+ "Delete the transaction surrounging POS."
(interactive "d")
- (let ((bounds (ledger-find-xact-extents pos)))
+ (let ((bounds (ledger-navigate-find-xact-extents pos)))
(delete-region (car bounds) (cadr bounds))))
(defun ledger-add-transaction (transaction-text &optional insert-at-point)
@@ -207,7 +191,6 @@ correct chronological place in the buffer."
(insert (car args) " \n\n")
(end-of-line -1)))))
-
(provide 'ledger-xact)
;;; ledger-xact.el ends here
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index aec75c06..7b10061f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -168,6 +168,9 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug")
list(APPEND _args ${CMAKE_SHARED_LIBRARY_CXX_FLAGS})
endif()
list(APPEND _args "-std=c++11 ")
+ if (CYGWIN)
+ list(APPEND _args "-U__STRICT_ANSI__")
+ endif()
list(APPEND _args "-x c++-header " ${_inc})
list(APPEND _args -c ${_header_filename} -o ${_pch_filename})
@@ -224,6 +227,9 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug")
endif()
list(APPEND _args ${GXX_WARNING_FLAGS})
list(APPEND _args "-std=c++11 ")
+ if (CYGWIN)
+ list(APPEND _args "-U__STRICT_ANSI__")
+ endif()
list(APPEND _args "-x c++-header " ${_inc})
list(APPEND _args -c ${_header_filename} -o ${_gch_filename})
diff --git a/src/account.cc b/src/account.cc
index 216b15bd..358aa09a 100644
--- a/src/account.cc
+++ b/src/account.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/account.h b/src/account.h
index d1377c39..76e839eb 100644
--- a/src/account.h
+++ b/src/account.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -261,7 +261,11 @@ public:
mutable optional<xdata_t> xdata_;
bool has_xdata() const {
+#if BOOST_VERSION >= 105600
+ return xdata_ != NULL;
+#else
return xdata_;
+#endif
}
void clear_xdata();
xdata_t& xdata() {
diff --git a/src/amount.cc b/src/amount.cc
index 5d74c22e..6ddcdb4f 100644
--- a/src/amount.cc
+++ b/src/amount.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/amount.h b/src/amount.h
index 8fadaf9d..ea5cadd6 100644
--- a/src/amount.h
+++ b/src/amount.h
@@ -1,9 +1,9 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * modification, are permitted provided that the following conditions are
+ * met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
diff --git a/src/annotate.cc b/src/annotate.cc
index 89363dd5..7c54edef 100644
--- a/src/annotate.cc
+++ b/src/annotate.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/annotate.h b/src/annotate.h
index 0f8f8e68..c0fbcd3d 100644
--- a/src/annotate.h
+++ b/src/annotate.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/archive.cc b/src/archive.cc
index 87faab3c..9ae04e85 100644
--- a/src/archive.cc
+++ b/src/archive.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/archive.h b/src/archive.h
index d5a5a90b..485f9606 100644
--- a/src/archive.h
+++ b/src/archive.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/balance.cc b/src/balance.cc
index 752bf133..36eab7d4 100644
--- a/src/balance.cc
+++ b/src/balance.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/balance.h b/src/balance.h
index ca1ee31b..752bb4d6 100644
--- a/src/balance.h
+++ b/src/balance.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/chain.cc b/src/chain.cc
index bb3955b8..42f474c4 100644
--- a/src/chain.cc
+++ b/src/chain.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/chain.h b/src/chain.h
index f9f5c6c6..224bed21 100644
--- a/src/chain.h
+++ b/src/chain.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/commodity.cc b/src/commodity.cc
index ae852462..398245fb 100644
--- a/src/commodity.cc
+++ b/src/commodity.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/commodity.h b/src/commodity.h
index 80945fe7..3d1ddf04 100644
--- a/src/commodity.h
+++ b/src/commodity.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/compare.cc b/src/compare.cc
index 34e41332..db169cfc 100644
--- a/src/compare.cc
+++ b/src/compare.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/compare.h b/src/compare.h
index defc38f3..554e84aa 100644
--- a/src/compare.h
+++ b/src/compare.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/context.h b/src/context.h
index 27b733a1..e787f335 100644
--- a/src/context.h
+++ b/src/context.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/convert.cc b/src/convert.cc
index 816271f2..a4454c14 100644
--- a/src/convert.cc
+++ b/src/convert.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/convert.h b/src/convert.h
index c82dd34c..020dfea2 100644
--- a/src/convert.h
+++ b/src/convert.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/csv.cc b/src/csv.cc
index 9f7e78e4..b0a54f4e 100644
--- a/src/csv.cc
+++ b/src/csv.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/csv.h b/src/csv.h
index 9c4ccca1..cda15ea3 100644
--- a/src/csv.h
+++ b/src/csv.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/draft.cc b/src/draft.cc
index 63173234..78e53ccd 100644
--- a/src/draft.cc
+++ b/src/draft.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/draft.h b/src/draft.h
index 39786ec8..7ba40640 100644
--- a/src/draft.h
+++ b/src/draft.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/emacs.cc b/src/emacs.cc
index b7f20bd2..dc16c002 100644
--- a/src/emacs.cc
+++ b/src/emacs.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/emacs.h b/src/emacs.h
index aecf884e..fef7a882 100644
--- a/src/emacs.h
+++ b/src/emacs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/error.cc b/src/error.cc
index 830dacb0..90697c5f 100644
--- a/src/error.cc
+++ b/src/error.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/error.h b/src/error.h
index c4aa2a71..31fa76a3 100644
--- a/src/error.h
+++ b/src/error.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/expr.cc b/src/expr.cc
index 84da6292..e38d794f 100644
--- a/src/expr.cc
+++ b/src/expr.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/expr.h b/src/expr.h
index 4909c21e..384cc661 100644
--- a/src/expr.h
+++ b/src/expr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/exprbase.h b/src/exprbase.h
index 17a8ad95..b88fcd7d 100644
--- a/src/exprbase.h
+++ b/src/exprbase.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/filters.cc b/src/filters.cc
index bdc2983b..2f97a0e5 100644
--- a/src/filters.cc
+++ b/src/filters.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -983,7 +983,7 @@ void interval_posts::flush()
sort_posts_by_date());
// Determine the beginning interval by using the earliest post
- if (all_posts.front() &&
+ if (all_posts.size() > 0 && all_posts.front() &&
! interval.find_period(all_posts.front()->date()))
throw_(std::logic_error, _("Failed to find period for interval report"));
diff --git a/src/filters.h b/src/filters.h
index 48d1a0fb..1404b38e 100644
--- a/src/filters.h
+++ b/src/filters.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/flags.h b/src/flags.h
index 910b70a7..f3593517 100644
--- a/src/flags.h
+++ b/src/flags.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/format.cc b/src/format.cc
index 402cfdfd..2887a387 100644
--- a/src/format.cc
+++ b/src/format.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/format.h b/src/format.h
index 3e16bbb5..6ac4075e 100644
--- a/src/format.h
+++ b/src/format.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/generate.cc b/src/generate.cc
index b69d7cd1..6503f414 100644
--- a/src/generate.cc
+++ b/src/generate.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/generate.h b/src/generate.h
index 622861e2..b17116fa 100644
--- a/src/generate.h
+++ b/src/generate.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/global.cc b/src/global.cc
index cc928c1b..602e216c 100644
--- a/src/global.cc
+++ b/src/global.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -388,7 +388,7 @@ void global_scope_t::read_environment_settings(char * envp[])
process_environment(const_cast<const char **>(envp), "LEDGER_", report());
#if 1
- // These are here for backwards compatability, but are deprecated.
+ // These are here for backwards compatibility, but are deprecated.
if (const char * p = std::getenv("LEDGER")) {
if (! std::getenv("LEDGER_FILE"))
@@ -514,7 +514,7 @@ void handle_debug_options(int argc, char * argv[])
#if TRACING_ON
_log_level = LOG_TRACE;
try {
- _trace_level = boost::lexical_cast<uint8_t>(argv[i + 1]);
+ _trace_level = boost::lexical_cast<uint16_t>(argv[i + 1]);
}
catch (const boost::bad_lexical_cast&) {
throw std::logic_error(_("Argument to --trace must be an integer"));
diff --git a/src/global.h b/src/global.h
index eda75112..f36dbe3d 100644
--- a/src/global.h
+++ b/src/global.h
@@ -1,9 +1,9 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * modification, are permitted provided that the following conditions are
+ * met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
@@ -127,7 +127,7 @@ public:
out << '-' << Ledger_VERSION_DATE;
out << _(", the command-line accounting tool");
out <<
- _("\n\nCopyright (c) 2003-2014, John Wiegley. All rights reserved.\n\n\
+ _("\n\nCopyright (c) 2003-2015, John Wiegley. All rights reserved.\n\n\
This program is made available under the terms of the BSD Public License.\n\
See LICENSE file included with the distribution for details and disclaimer.");
out << std::endl;
diff --git a/src/history.cc b/src/history.cc
index 3601c093..e3c459f3 100644
--- a/src/history.cc
+++ b/src/history.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/history.h b/src/history.h
index 68c46189..dd776383 100644
--- a/src/history.h
+++ b/src/history.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/item.cc b/src/item.cc
index 551c8fef..9effcd23 100644
--- a/src/item.cc
+++ b/src/item.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/item.h b/src/item.h
index beb32a04..458cb378 100644
--- a/src/item.h
+++ b/src/item.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -191,7 +191,11 @@ public:
static bool use_aux_date;
virtual bool has_date() const {
+#if BOOST_VERSION >= 105600
+ return _date != NULL;
+#else
return _date;
+#endif
}
virtual date_t date() const {
diff --git a/src/iterators.cc b/src/iterators.cc
index fd6cde69..21bec5d9 100644
--- a/src/iterators.cc
+++ b/src/iterators.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/iterators.h b/src/iterators.h
index 93d0d7ce..86eb86ca 100644
--- a/src/iterators.h
+++ b/src/iterators.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/journal.cc b/src/journal.cc
index b11b5c45..ae545477 100644
--- a/src/journal.cc
+++ b/src/journal.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/journal.h b/src/journal.h
index 803b9511..613b2b96 100644
--- a/src/journal.h
+++ b/src/journal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/lookup.cc b/src/lookup.cc
index aa1eeb65..6dbeb502 100644
--- a/src/lookup.cc
+++ b/src/lookup.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/lookup.h b/src/lookup.h
index 60ef334b..fc7063ec 100644
--- a/src/lookup.h
+++ b/src/lookup.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/main.cc b/src/main.cc
index 81118e43..c26a280a 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/mask.cc b/src/mask.cc
index 5c5d02f9..29b53781 100644
--- a/src/mask.cc
+++ b/src/mask.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/mask.h b/src/mask.h
index 296892c8..2b579768 100644
--- a/src/mask.h
+++ b/src/mask.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/op.cc b/src/op.cc
index 5794794e..ff707a14 100644
--- a/src/op.cc
+++ b/src/op.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/op.h b/src/op.h
index 99838f86..c45ffb08 100644
--- a/src/op.h
+++ b/src/op.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/option.cc b/src/option.cc
index 0629399e..8c003e08 100644
--- a/src/option.cc
+++ b/src/option.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/option.h b/src/option.h
index 1ea9457d..4646121d 100644
--- a/src/option.h
+++ b/src/option.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/org.cc b/src/org.cc
index 34ca6de3..7d11c36a 100644
--- a/src/org.cc
+++ b/src/org.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/org.h b/src/org.h
index 6e78350d..40b7685d 100644
--- a/src/org.h
+++ b/src/org.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/output.cc b/src/output.cc
index ba469ea9..ffd144e1 100644
--- a/src/output.cc
+++ b/src/output.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/output.h b/src/output.h
index 38f1e59e..ec7ec6c2 100644
--- a/src/output.h
+++ b/src/output.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/parser.cc b/src/parser.cc
index 7fbbff8a..8044338f 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/parser.h b/src/parser.h
index a056493a..e46fc719 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/pool.cc b/src/pool.cc
index 71bfab72..95c0f49d 100644
--- a/src/pool.cc
+++ b/src/pool.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/pool.h b/src/pool.h
index f93f3496..d24df78c 100644
--- a/src/pool.h
+++ b/src/pool.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/post.cc b/src/post.cc
index 4244a349..269e2e6c 100644
--- a/src/post.cc
+++ b/src/post.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/post.h b/src/post.h
index c2f77b32..1e5fc569 100644
--- a/src/post.h
+++ b/src/post.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -205,7 +205,11 @@ public:
mutable optional<xdata_t> xdata_;
bool has_xdata() const {
+#if BOOST_VERSION >= 105600
+ return xdata_ != NULL;
+#else
return xdata_;
+#endif
}
void clear_xdata() {
xdata_ = none;
diff --git a/src/precmd.cc b/src/precmd.cc
index edd824f1..2da6ba8e 100644
--- a/src/precmd.cc
+++ b/src/precmd.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/precmd.h b/src/precmd.h
index f25fcb43..bf2732d7 100644
--- a/src/precmd.h
+++ b/src/precmd.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/predicate.h b/src/predicate.h
index 964d4418..30d07223 100644
--- a/src/predicate.h
+++ b/src/predicate.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/print.cc b/src/print.cc
index 54cfa578..02e518f7 100644
--- a/src/print.cc
+++ b/src/print.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/print.h b/src/print.h
index e882922e..c587b499 100644
--- a/src/print.h
+++ b/src/print.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/pstream.h b/src/pstream.h
index ed314068..3b669aca 100644
--- a/src/pstream.h
+++ b/src/pstream.h
@@ -1,9 +1,9 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * modification, are permitted provided that the following conditions are
+ * met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
diff --git a/src/ptree.cc b/src/ptree.cc
index 6609aed9..3efe4451 100644
--- a/src/ptree.cc
+++ b/src/ptree.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -80,7 +80,12 @@ void format_ptree::flush()
switch (format) {
case FORMAT_XML:
+#if BOOST_VERSION >= 105600
+ auto indented = property_tree::xml_writer_make_settings<std::string> (' ', 2);
+#else
property_tree::xml_writer_settings<char> indented(' ', 2);
+#endif
+
property_tree::write_xml(out, pt, indented);
out << std::endl;
break;
diff --git a/src/ptree.h b/src/ptree.h
index dc1161f3..36708dcf 100644
--- a/src/ptree.h
+++ b/src/ptree.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/py_account.cc b/src/py_account.cc
index 3054512e..1cc28b92 100644
--- a/src/py_account.cc
+++ b/src/py_account.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -35,6 +35,7 @@
#include "pyutils.h"
#include "account.h"
#include "post.h"
+#include "expr.h"
namespace ledger {
@@ -97,6 +98,26 @@ namespace {
return str_to_py_unicode(account.fullname());
}
+ value_t py_amount_0(const account_t& account)
+ {
+ return account.amount();
+ }
+
+ value_t py_amount_1(const account_t& account, const boost::optional<expr_t&>& expr)
+ {
+ return account.amount(expr);
+ }
+
+ value_t py_total_0(const account_t& account)
+ {
+ return account.total();
+ }
+
+ value_t py_total_1(const account_t& account, const boost::optional<expr_t&>& expr)
+ {
+ return account.total(expr);
+ }
+
} // unnamed namespace
void export_account()
@@ -221,8 +242,10 @@ void export_account()
.def("xdata", py_xdata,
return_internal_reference<>())
- .def("amount", &account_t::amount)
- .def("total", &account_t::total)
+ .def("amount", py_amount_0)
+ .def("amount", py_amount_1, args("expr"))
+ .def("total", py_total_0)
+ .def("total", py_total_1, args("expr"))
.def("self_details", &account_t::self_details,
return_internal_reference<>())
diff --git a/src/py_amount.cc b/src/py_amount.cc
index 01fb370c..84558a29 100644
--- a/src/py_amount.cc
+++ b/src/py_amount.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/py_balance.cc b/src/py_balance.cc
index 8bf30050..98ed8c60 100644
--- a/src/py_balance.cc
+++ b/src/py_balance.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -56,6 +56,11 @@ namespace {
const datetime_t& moment) {
return balance.value(moment, in_terms_of);
}
+ boost::optional<balance_t> py_value_2d(const balance_t& balance,
+ const commodity_t * in_terms_of,
+ const date_t& moment) {
+ return balance.value(datetime_t(moment), in_terms_of);
+ }
boost::optional<amount_t>
py_commodity_amount_0(const balance_t& balance) {
@@ -64,7 +69,7 @@ namespace {
boost::optional<amount_t>
py_commodity_amount_1(const balance_t& balance,
- const boost::optional<const commodity_t&>& commodity) {
+ const commodity_t& commodity) {
return balance.commodity_amount(commodity);
}
@@ -200,6 +205,7 @@ void export_balance()
.def("value", py_value_0)
.def("value", py_value_1, args("in_terms_of"))
.def("value", py_value_2, args("in_terms_of", "moment"))
+ .def("value", py_value_2d, args("in_terms_of", "moment"))
.def("__nonzero__", &balance_t::is_nonzero)
.def("is_nonzero", &balance_t::is_nonzero)
diff --git a/src/py_commodity.cc b/src/py_commodity.cc
index 18903a86..27a0e105 100644
--- a/src/py_commodity.cc
+++ b/src/py_commodity.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/py_expr.cc b/src/py_expr.cc
index c62cb3e1..803388f2 100644
--- a/src/py_expr.cc
+++ b/src/py_expr.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/py_format.cc b/src/py_format.cc
index ba590e62..6086d6cb 100644
--- a/src/py_format.cc
+++ b/src/py_format.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/py_item.cc b/src/py_item.cc
index 5d9a4ae2..473bbef8 100644
--- a/src/py_item.cc
+++ b/src/py_item.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/py_journal.cc b/src/py_journal.cc
index cc2b996d..abbcd866 100644
--- a/src/py_journal.cc
+++ b/src/py_journal.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/py_post.cc b/src/py_post.cc
index d6ff5402..851828c7 100644
--- a/src/py_post.cc
+++ b/src/py_post.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/py_session.cc b/src/py_session.cc
index 25d13cc0..f6053180 100644
--- a/src/py_session.cc
+++ b/src/py_session.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -61,6 +61,8 @@ void export_session()
.def("read_journal_files", &session_t::read_journal_files,
return_internal_reference<>())
.def("close_journal_files", &session_t::close_journal_files)
+ .def("journal", &session_t::get_journal,
+ return_internal_reference<>())
;
scope().attr("session") =
diff --git a/src/py_times.cc b/src/py_times.cc
index c210889d..906dcfaa 100644
--- a/src/py_times.cc
+++ b/src/py_times.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/py_utils.cc b/src/py_utils.cc
index 0dc3d2bf..df87bded 100644
--- a/src/py_utils.cc
+++ b/src/py_utils.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/py_value.cc b/src/py_value.cc
index 669e0d73..2828e3b8 100644
--- a/src/py_value.cc
+++ b/src/py_value.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/py_xact.cc b/src/py_xact.cc
index 5e355ad9..5b4c14d4 100644
--- a/src/py_xact.cc
+++ b/src/py_xact.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/pyfstream.h b/src/pyfstream.h
index d1aca260..11f514a2 100644
--- a/src/pyfstream.h
+++ b/src/pyfstream.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/pyinterp.cc b/src/pyinterp.cc
index 9d6638fc..54e62946 100644
--- a/src/pyinterp.cc
+++ b/src/pyinterp.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/pyinterp.h b/src/pyinterp.h
index 5ea40567..32becbf6 100644
--- a/src/pyinterp.h
+++ b/src/pyinterp.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/pyledger.cc b/src/pyledger.cc
index 27a07deb..1f478dec 100644
--- a/src/pyledger.cc
+++ b/src/pyledger.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/pyutils.h b/src/pyutils.h
index 0a50d0eb..039b2605 100644
--- a/src/pyutils.h
+++ b/src/pyutils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/query.cc b/src/query.cc
index 7e96b040..04b18581 100644
--- a/src/query.cc
+++ b/src/query.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/query.h b/src/query.h
index f2161eb8..b7608bc7 100644
--- a/src/query.h
+++ b/src/query.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/quotes.cc b/src/quotes.cc
index c29f18d0..6d179287 100644
--- a/src/quotes.cc
+++ b/src/quotes.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/quotes.h b/src/quotes.h
index 34c506dd..c14bc495 100644
--- a/src/quotes.h
+++ b/src/quotes.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/report.cc b/src/report.cc
index 7bb79bd1..4b240611 100644
--- a/src/report.cc
+++ b/src/report.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -181,10 +181,17 @@ void report_t::normalize_options(const string& verb)
}
long cols = 0;
+#if HAVE_IOCTL
+ struct winsize ws;
+#endif
if (HANDLED(columns_))
cols = lexical_cast<long>(HANDLER(columns_).value);
else if (const char * columns = std::getenv("COLUMNS"))
cols = lexical_cast<long>(columns);
+#if HAVE_IOCTL
+ else if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) != -1)
+ cols = ws.ws_col;
+#endif
else
cols = 80L;
diff --git a/src/report.h b/src/report.h
index c500fb9b..67e95884 100644
--- a/src/report.h
+++ b/src/report.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -465,8 +465,8 @@ public:
" 12 + 1 + 12 + 1 + 12, true, color))"
" %(ansify_if("
" justify((get_at(display_total, 1) ? "
- " (100% * scrub(get_at(display_total, 0))) / "
- " -scrub(get_at(display_total, 1)) : 0), "
+ " (100% * quantity(scrub(get_at(display_total, 0)))) / "
+ " -quantity(scrub(get_at(display_total, 1))) : 0), "
" 5, -1, true, false),"
" magenta if (color and get_at(display_total, 1) and "
" (abs(quantity(scrub(get_at(display_total, 0))) / "
diff --git a/src/scope.cc b/src/scope.cc
index 7eaf50c3..3ca9e0c0 100644
--- a/src/scope.cc
+++ b/src/scope.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/scope.h b/src/scope.h
index 30b825a3..8ad3afac 100644
--- a/src/scope.h
+++ b/src/scope.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/select.cc b/src/select.cc
index 45ae34be..81800f16 100644
--- a/src/select.cc
+++ b/src/select.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -145,10 +145,17 @@ value_t select_command(call_scope_t& args)
string thus_far = "";
std::size_t cols = 0;
+#if HAVE_IOCTL
+ struct winsize ws;
+#endif
if (report.HANDLED(columns_))
cols = lexical_cast<std::size_t>(report.HANDLER(columns_).value);
else if (const char * columns_env = std::getenv("COLUMNS"))
cols = lexical_cast<std::size_t>(columns_env);
+#if HAVE_IOCTL
+ else if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) != -1)
+ cols = ws.ws_col;
+#endif
else
cols = 80;
diff --git a/src/select.h b/src/select.h
index 09555db8..c95e15f7 100644
--- a/src/select.h
+++ b/src/select.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/session.cc b/src/session.cc
index e373eb03..b0d31be9 100644
--- a/src/session.cc
+++ b/src/session.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -265,6 +265,11 @@ void session_t::close_journal_files()
amount_t::initialize();
}
+journal_t * session_t::get_journal()
+{
+ return journal.get();
+}
+
value_t session_t::fn_account(call_scope_t& args)
{
if (args[0].is_string())
diff --git a/src/session.h b/src/session.h
index d20ba74a..b287b19e 100644
--- a/src/session.h
+++ b/src/session.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -84,6 +84,8 @@ public:
journal_t * read_journal_files();
void close_journal_files();
+ journal_t * get_journal();
+
value_t fn_account(call_scope_t& scope);
value_t fn_min(call_scope_t& scope);
value_t fn_max(call_scope_t& scope);
diff --git a/src/stats.cc b/src/stats.cc
index 31bceea3..406ecd3b 100644
--- a/src/stats.cc
+++ b/src/stats.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/stats.h b/src/stats.h
index 7502fc20..f0408591 100644
--- a/src/stats.h
+++ b/src/stats.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/stream.cc b/src/stream.cc
index e4eb7800..c5a40e87 100644
--- a/src/stream.cc
+++ b/src/stream.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/stream.h b/src/stream.h
index 577a3291..05572cb4 100644
--- a/src/stream.h
+++ b/src/stream.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/system.hh.in b/src/system.hh.in
index eaee14dc..21417e09 100644
--- a/src/system.hh.in
+++ b/src/system.hh.in
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -63,6 +63,7 @@
#define HAVE_REALPATH @HAVE_REALPATH@
#define HAVE_GETPWUID @HAVE_GETPWUID@
#define HAVE_GETPWNAM @HAVE_GETPWNAM@
+#define HAVE_IOCTL @HAVE_IOCTL@
#define HAVE_ISATTY @HAVE_ISATTY@
#define HAVE_UNIX_PIPES @HAVE_UNIX_PIPES@
@@ -151,6 +152,10 @@ typedef std::ostream::pos_type ostream_pos_type;
#include <pwd.h>
#endif
+#if HAVE_IOCTL
+#include <sys/ioctl.h>
+#endif
+
#if HAVE_UNIX_PIPES
#include <sys/types.h>
#include <sys/wait.h>
diff --git a/src/temps.cc b/src/temps.cc
index 75669a2a..15ccbc3a 100644
--- a/src/temps.cc
+++ b/src/temps.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/temps.h b/src/temps.h
index eedea4c1..77a7824e 100644
--- a/src/temps.h
+++ b/src/temps.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/textual.cc b/src/textual.cc
index 156e2b9c..8007ca0d 100644
--- a/src/textual.cc
+++ b/src/textual.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -285,6 +285,11 @@ void instance_t::parse()
}
}
+ if (apply_stack.front().value.type() == typeid(optional<datetime_t>))
+ epoch = boost::get<optional<datetime_t> >(apply_stack.front().value);
+
+ apply_stack.pop_front();
+
#if defined(TIMELOG_SUPPORT)
timelog.close();
#endif // TIMELOG_SUPPORT
@@ -419,7 +424,9 @@ void instance_t::read_next_directive(bool& error_flag)
price_xact_directive(line);
break;
case 'Y': // set the current year
- apply_year_directive(line + 1);
+ if (std::strlen(line+1) == 0)
+ throw_(parse_error, _f("Directive '%1%' requires an argument") % line[0]);
+ apply_year_directive(line+1);
break;
}
}
@@ -863,14 +870,17 @@ void instance_t::apply_rate_directive(char * line)
void instance_t::apply_year_directive(char * line)
{
- apply_stack.push_front(application_t("year", epoch));
-
- // This must be set to the last day of the year, otherwise partial
- // dates like "11/01" will refer to last year's november, not the
- // current year.
- unsigned short year(lexical_cast<unsigned short>(skip_ws(line)));
- DEBUG("times.epoch", "Setting current year to " << year);
- epoch = datetime_t(date_t(year, 12, 31));
+ try {
+ unsigned short year(lexical_cast<unsigned short>(skip_ws(line)));
+ apply_stack.push_front(application_t("year", epoch));
+ DEBUG("times.epoch", "Setting current year to " << year);
+ // This must be set to the last day of the year, otherwise partial
+ // dates like "11/01" will refer to last year's november, not the
+ // current year.
+ epoch = datetime_t(date_t(year, 12, 31));
+ } catch(bad_lexical_cast &) {
+ throw_(parse_error, _f("Argument '%1%' not a valid year") % skip_ws(line));
+ }
}
void instance_t::end_apply_directive(char * kind)
@@ -1245,13 +1255,13 @@ void instance_t::python_directive(char * line)
void instance_t::import_directive(char *)
{
throw_(parse_error,
- _("'python' directive seen, but Python support is missing"));
+ _("'import' directive seen, but Python support is missing"));
}
void instance_t::python_directive(char *)
{
throw_(parse_error,
- _("'import' directive seen, but Python support is missing"));
+ _("'python' directive seen, but Python support is missing"));
}
#endif // HAVE_BOOST_PYTHON
@@ -1375,6 +1385,13 @@ bool instance_t::general_directive(char * line)
return true;
}
break;
+
+ case 'y':
+ if (std::strcmp(p, "year") == 0) {
+ apply_year_directive(arg);
+ return true;
+ }
+ break;
}
if (expr_t::ptr_op_t op = lookup(symbol_t::DIRECTIVE, p)) {
@@ -1816,7 +1833,7 @@ xact_t * instance_t::parse_xact(char * line,
char *q = p - 1;
while (q > next && std::isspace(*q))
--q;
- if (q > next)
+ if (q >= next)
*(q + 1) = '\0';
break;
}
diff --git a/src/timelog.cc b/src/timelog.cc
index 8f157d62..91ee2697 100644
--- a/src/timelog.cc
+++ b/src/timelog.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/timelog.h b/src/timelog.h
index 50c93aab..af621ee6 100644
--- a/src/timelog.h
+++ b/src/timelog.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/times.cc b/src/times.cc
index b527de87..b6c15dc3 100644
--- a/src/times.cc
+++ b/src/times.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -839,7 +839,7 @@ void date_parser_t::determine_when(date_parser_t::lexer_t::token_t& tok,
specifier.month =
date_specifier_t::month_type
(boost::get<date_time::months_of_year>(*tok.value));
- tok = lexer.next_token();
+ tok = lexer.peek_token();
switch (tok.kind) {
case lexer_t::token_t::TOK_A_YEAR:
specifier.year = boost::get<date_specifier_t::year_type>(*tok.value);
@@ -847,7 +847,6 @@ void date_parser_t::determine_when(date_parser_t::lexer_t::token_t& tok,
case lexer_t::token_t::END_REACHED:
break;
default:
- tok.unexpected();
break;
}
break;
@@ -1813,6 +1812,7 @@ void times_initialize()
readers.push_back(shared_ptr<date_io_t>(new date_io_t("%Y/%m/%d", true)));
readers.push_back(shared_ptr<date_io_t>(new date_io_t("%Y/%m", true)));
readers.push_back(shared_ptr<date_io_t>(new date_io_t("%y/%m/%d", true)));
+ readers.push_back(shared_ptr<date_io_t>(new date_io_t("%Y-%m-%d", true)));
is_initialized = true;
}
diff --git a/src/times.h b/src/times.h
index 2a5b9277..c1bfb1cc 100644
--- a/src/times.h
+++ b/src/times.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -568,7 +568,11 @@ public:
void stabilize(const optional<date_t>& date = none);
bool is_valid() const {
+#if BOOST_VERSION >= 105600
+ return start != NULL;
+#else
return start;
+#endif
}
/** Find the current or next period containing date. Returns false if
diff --git a/src/token.cc b/src/token.cc
index aa78cd5a..9fe7873f 100644
--- a/src/token.cc
+++ b/src/token.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/token.h b/src/token.h
index febd8620..3fe249aa 100644
--- a/src/token.h
+++ b/src/token.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/unistring.h b/src/unistring.h
index 340115eb..3f459d83 100644
--- a/src/unistring.h
+++ b/src/unistring.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/utils.cc b/src/utils.cc
index 741ce79d..9b528f54 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -574,7 +574,7 @@ std::ostream * _log_stream = &std::cerr;
std::ostringstream _log_buffer;
#if TRACING_ON
-uint8_t _trace_level;
+uint16_t _trace_level;
#endif
static bool logger_has_run = false;
diff --git a/src/utils.h b/src/utils.h
index c3dcf562..b92a6f49 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -251,7 +251,7 @@ void logger_func(log_level_t level);
#if TRACING_ON
-extern uint8_t _trace_level;
+extern uint16_t _trace_level;
#define SHOW_TRACE(lvl) \
(ledger::_log_level >= ledger::LOG_TRACE && lvl <= ledger::_trace_level)
diff --git a/src/value.cc b/src/value.cc
index 2c62f4e1..4ea7c7a8 100644
--- a/src/value.cc
+++ b/src/value.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/value.h b/src/value.h
index 3308e160..c224ce04 100644
--- a/src/value.h
+++ b/src/value.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/views.cc b/src/views.cc
index f0931e87..61b824cd 100644
--- a/src/views.cc
+++ b/src/views.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/views.h b/src/views.h
index bc4e5011..2be3d978 100644
--- a/src/views.h
+++ b/src/views.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/src/xact.cc b/src/xact.cc
index 3e563714..5369c138 100644
--- a/src/xact.cc
+++ b/src/xact.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -185,7 +185,7 @@ bool xact_base_t::finalize()
if (post_account_bad || null_post_account_bad)
throw_(std::logic_error,
- _f("Posting with null amount's account may be mispelled:\n \"%1%\"")
+ _f("Posting with null amount's account may be misspelled:\n \"%1%\"")
% (post_account_bad ? post->account->fullname() :
null_post->account->fullname()));
else
diff --git a/src/xact.h b/src/xact.h
index 074791b3..3ca57953 100644
--- a/src/xact.h
+++ b/src/xact.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2014, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2015, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 0f19ae6f..44db81fb 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -6,8 +6,6 @@ if (NOT PROCESSORS EQUAL 0)
set(CTEST_BUILD_FLAGS -j${JOBS})
endif()
-get_target_property(LEDGER_LOCATION ledger LOCATION)
-
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} ${CTEST_BUILD_FLAGS})
add_subdirectory(unit)
@@ -23,9 +21,9 @@ macro(add_ledger_harness_tests _class)
get_filename_component(TestFile_Name ${TestFile} NAME_WE)
string(FIND ${TestFile_Name} "_py" TestFile_IsPythonTest)
if ((TestFile_IsPythonTest EQUAL -1) OR HAVE_BOOST_PYTHON)
- add_test(${_class}Test_${TestFile_Name}
- ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/test/RegressTests.py
- ${LEDGER_LOCATION} ${PROJECT_SOURCE_DIR}
+ add_test(NAME ${_class}Test_${TestFile_Name}
+ COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/test/RegressTests.py
+ $<TARGET_FILE:ledger> ${PROJECT_SOURCE_DIR}
${TestFile} ${TEST_PYTHON_FLAGS})
set_target_properties(check
PROPERTIES DEPENDS ${_class}Test_${TestFile_Name})
@@ -38,17 +36,16 @@ add_subdirectory(manual)
add_subdirectory(baseline)
add_subdirectory(regress)
-# jww (2014-04-17): This is temporary until we find a fix.
-#if (PYTHONINTERP_FOUND)
-# set(_class DocTests)
-# file(GLOB ${_class}_TESTS ${PROJECT_SOURCE_DIR}/doc/*.texi)
-# foreach(TestFile ${${_class}_TESTS})
-# get_filename_component(TestFile_Name ${TestFile} NAME_WE)
-# add_test(${_class}Test_${TestFile_Name}
-# ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/test/DocTests.py
-# --ledger ${LEDGER_LOCATION} --file ${TestFile})
-# set_target_properties(check PROPERTIES DEPENDS ${_class}Test_${TestFile_Name})
-# endforeach()
-#endif()
+if (PYTHONINTERP_FOUND)
+ set(_class DocTests)
+ file(GLOB ${_class}_TESTS ${PROJECT_SOURCE_DIR}/doc/*.texi)
+ foreach(TestFile ${${_class}_TESTS})
+ get_filename_component(TestFile_Name ${TestFile} NAME_WE)
+ add_test(NAME ${_class}Test_${TestFile_Name}
+ COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/test/DocTests.py
+ --ledger $<TARGET_FILE:ledger> --file ${TestFile})
+ set_target_properties(check PROPERTIES DEPENDS ${_class}Test_${TestFile_Name})
+ endforeach()
+endif()
### CMakeLists.txt ends here
diff --git a/test/DocTests.py b/test/DocTests.py
index d2931686..ea32608e 100755
--- a/test/DocTests.py
+++ b/test/DocTests.py
@@ -16,6 +16,7 @@ class DocTests:
self.ledger = os.path.abspath(args.ledger)
self.sourcepath = os.path.abspath(args.file)
self.verbose = args.verbose
+ self.tests = args.examples
self.examples = dict()
self.test_files = list()
@@ -114,8 +115,9 @@ class DocTests:
if command[0] == '$': command.remove('$')
index = command.index('ledger')
command[index] = self.ledger
- command.insert(index+1, '--init-file')
- command.insert(index+2, '/dev/null')
+ for i,argument in enumerate('--args-only --columns 80'.split()):
+ command.insert(index+i+1, argument)
+
try:
findex = command.index('-f')
except ValueError:
@@ -132,7 +134,14 @@ class DocTests:
def test_examples(self):
failed = set()
- for test_id in self.examples:
+ tests = self.examples.keys()
+ if self.tests:
+ tests = list(set(self.tests).intersection(tests))
+ temp = list(set(self.tests).difference(tests))
+ if len(temp) > 0:
+ print >> sys.stderr, 'Skipping non-existent examples: %s' % ', '.join(temp)
+
+ for test_id in tests:
validation = False
if "validate-data" in self.examples[test_id] or "validate-command" in self.examples[test_id]:
validation = True
@@ -212,7 +221,7 @@ class DocTests:
if __name__ == "__main__":
def getargs():
- parser = argparse.ArgumentParser(description='DocTests', prefix_chars='-')
+ parser = argparse.ArgumentParser(prog='DocTests', description='Test ledger examples from the documentation', prefix_chars='-')
parser.add_argument('-v', '--verbose',
dest='verbose',
action='count',
@@ -229,6 +238,11 @@ if __name__ == "__main__":
action='store',
required=True,
help='the texinfo documentation file to run the examples from')
+ parser.add_argument('examples',
+ metavar='EXAMPLE',
+ type=str,
+ nargs='*',
+ help='the examples to test')
return parser.parse_args()
args = getargs()
diff --git a/test/baseline/opt-primary-date.test b/test/baseline/opt-primary-date.test
index e69de29b..e433a8f9 100644
--- a/test/baseline/opt-primary-date.test
+++ b/test/baseline/opt-primary-date.test
@@ -0,0 +1,99 @@
+; primary-date display primary dates for all calculations
+2014/01/01=2014/01/13 Client invoice ; estimated date you'll be paid
+ Assets:Accounts Receivable $100.00
+ Income: Client ABC
+
+2014/01/01=2014/01/15 Client invoice ; actual date money received
+ Assets:Accounts Receivable $100.00
+ Income: Client ABC
+
+; will not affect checking account
+2013/10/16 * (2090) Bountiful Blessings Farm
+ Expenses:Food:Groceries $ 37.50 ; [=2013/10/01]
+ Expenses:Food:Groceries $ 37.50 ; [=2013/11/01]
+ Expenses:Food:Groceries $ 37.50 ; [=2013/12/01]
+ Expenses:Food:Groceries $ 37.50 ; [=2014/01/01]
+ Expenses:Food:Groceries $ 37.50 ; [=2014/02/01]
+ Expenses:Food:Groceries $ 37.50 ; [=2014/03/01]
+ Assets:Checking
+
+
+test bal Income --begin 2014/01/01 --end 2014/01/14
+ $ -200.00 Income: Client ABC
+end test
+
+test bal Income --effective --begin 2014/01/01 --end 2014/01/14
+ $ -100.00 Income: Client ABC
+end test
+
+test bal Income --primary-date --effective --begin 2014/01/01 --end 2014/01/14
+ $ -200.00 Income: Client ABC
+end test
+
+test bal Income --actual-dates --effective --begin 2014/01/01 --end 2014/01/14
+ $ -200.00 Income: Client ABC
+end test
+
+test reg Income --begin 2014/01/01 --end 2014/01/14
+14-Jan-01 Client invoice Income: Client ABC $ -100.00 $ -100.00
+14-Jan-01 Client invoice Income: Client ABC $ -100.00 $ -200.00
+end test
+
+test reg Income --effective --begin 2014/01/01 --end 2014/01/14
+14-Jan-13 Client invoice Income: Client ABC $ -100.00 $ -100.00
+end test
+
+test reg Income --primary-date --effective --begin 2014/01/01 --end 2014/01/14
+14-Jan-01 Client invoice Income: Client ABC $ -100.00 $ -100.00
+14-Jan-01 Client invoice Income: Client ABC $ -100.00 $ -200.00
+end test
+
+test reg Income --actual-dates --effective --begin 2014/01/01 --end 2014/01/14
+14-Jan-01 Client invoice Income: Client ABC $ -100.00 $ -100.00
+14-Jan-01 Client invoice Income: Client ABC $ -100.00 $ -200.00
+end test
+
+test reg checking
+13-Oct-16 Bountiful Blessings.. Assets:Checking $ -225.00 $ -225.00
+end test
+
+test reg checking --primary-date --effective
+13-Oct-16 Bountiful Blessings.. Assets:Checking $ -225.00 $ -225.00
+end test
+
+test register Groceries
+13-Oct-16 Bountiful Blessings.. Expense:Food:Groceries $ 37.50 $ 37.50
+ Expense:Food:Groceries $ 37.50 $ 75.00
+ Expense:Food:Groceries $ 37.50 $ 112.50
+ Expense:Food:Groceries $ 37.50 $ 150.00
+ Expense:Food:Groceries $ 37.50 $ 187.50
+ Expense:Food:Groceries $ 37.50 $ 225.00
+end test
+
+test register Groceries --effective
+13-Oct-01 Bountiful Blessings.. Expense:Food:Groceries $ 37.50 $ 37.50
+13-Nov-01 Bountiful Blessings.. Expense:Food:Groceries $ 37.50 $ 75.00
+13-Dec-01 Bountiful Blessings.. Expense:Food:Groceries $ 37.50 $ 112.50
+14-Jan-01 Bountiful Blessings.. Expense:Food:Groceries $ 37.50 $ 150.00
+14-Feb-01 Bountiful Blessings.. Expense:Food:Groceries $ 37.50 $ 187.50
+14-Mar-01 Bountiful Blessings.. Expense:Food:Groceries $ 37.50 $ 225.00
+end test
+
+test register Groceries --primary-date --effective
+13-Oct-16 Bountiful Blessings.. Expense:Food:Groceries $ 37.50 $ 37.50
+ Expense:Food:Groceries $ 37.50 $ 75.00
+ Expense:Food:Groceries $ 37.50 $ 112.50
+ Expense:Food:Groceries $ 37.50 $ 150.00
+ Expense:Food:Groceries $ 37.50 $ 187.50
+ Expense:Food:Groceries $ 37.50 $ 225.00
+end test
+
+test register Groceries --actual-dates --effective
+13-Oct-16 Bountiful Blessings.. Expense:Food:Groceries $ 37.50 $ 37.50
+ Expense:Food:Groceries $ 37.50 $ 75.00
+ Expense:Food:Groceries $ 37.50 $ 112.50
+ Expense:Food:Groceries $ 37.50 $ 150.00
+ Expense:Food:Groceries $ 37.50 $ 187.50
+ Expense:Food:Groceries $ 37.50 $ 225.00
+end test
+
diff --git a/test/baseline/opt-trace.test b/test/baseline/opt-trace.test
new file mode 100644
index 00000000..9034018e
--- /dev/null
+++ b/test/baseline/opt-trace.test
@@ -0,0 +1,15 @@
+2007/02/02 RD VMMXX
+ Assets:Investments:Vanguard:VMMXX 0.350 VMMXX @ $1.00
+ Income:Dividends:Vanguard:VMMXX $-0.35
+
+; Using values with two or more digits as the argument to the --trace option
+; resulted in a segmentation fault.
+; Since ledger prints debugging information to stderr when the --trace option
+; was given and that debugging information contains timing information, e.g. [1ms]
+; which is likely to differ on each test run, this test only checks that ledger
+; does not crash when the --trace options was specified.
+test reg --trace 10 2>/dev/null
+07-Feb-02 RD VMMXX As:Inves:Vanguar:VMMXX 0.350 VMMXX 0.350 VMMXX
+ In:Divid:Vanguar:VMMXX $-0.35 $-0.35
+ 0.350 VMMXX
+end test
diff --git a/test/convert.py b/test/convert.py
index ae44b39f..5328c4ae 100755
--- a/test/convert.py
+++ b/test/convert.py
@@ -3,7 +3,7 @@
# convert.py: This script converts a Boost.Test unit test into an
# equivalent Python unit test.
#
-# Copyright (c) 2003-2010, John Wiegley. All rights reserved.
+# Copyright (c) 2003-2015, John Wiegley. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
diff --git a/test/regress/1038_1.test b/test/regress/1038_1.test
new file mode 100644
index 00000000..c833816e
--- /dev/null
+++ b/test/regress/1038_1.test
@@ -0,0 +1,18 @@
+Y2014
+
+04/13 Bank
+ Expenses:Loan $400
+ Assets:Cash
+
+05/13 Bug 1038 Test
+ Expenses:Some:Account $500
+ Assets:Cash
+
+06/13 Landlord
+ Expenses:Rent $600
+ Assets:Cash
+
+test reg --now 2014-05-14 -p 'this month'
+14-May-13 Bug 1038 Test Expenses:Some:Account $500 $500
+ Assets:Cash $-500 0
+end test
diff --git a/test/regress/1038_2.test b/test/regress/1038_2.test
new file mode 100644
index 00000000..ce0c046d
--- /dev/null
+++ b/test/regress/1038_2.test
@@ -0,0 +1,18 @@
+year 2014
+
+04/13 Bank
+ Expenses:Loan $400
+ Assets:Cash
+
+05/13 Bug 1038 Test
+ Expenses:Some:Account $500
+ Assets:Cash
+
+06/13 Landlord
+ Expenses:Rent $600
+ Assets:Cash
+
+test reg --now 2014-05-14 -p 'this month'
+14-May-13 Bug 1038 Test Expenses:Some:Account $500 $500
+ Assets:Cash $-500 0
+end test
diff --git a/test/regress/1038_3.test b/test/regress/1038_3.test
new file mode 100644
index 00000000..0e277d71
--- /dev/null
+++ b/test/regress/1038_3.test
@@ -0,0 +1,20 @@
+apply year 2014
+
+04/13 Bank
+ Expenses:Loan $400
+ Assets:Cash
+
+05/13 Bug 1038 Test
+ Expenses:Some:Account $500
+ Assets:Cash
+
+06/13 Landlord
+ Expenses:Rent $600
+ Assets:Cash
+
+end apply
+
+test reg --now 2014-05-14 -p 'this month'
+14-May-13 Bug 1038 Test Expenses:Some:Account $500 $500
+ Assets:Cash $-500 0
+end test
diff --git a/test/regress/1072.test b/test/regress/1072.test
new file mode 100644
index 00000000..3f58b83f
--- /dev/null
+++ b/test/regress/1072.test
@@ -0,0 +1,31 @@
+
+--input-date-format %d/%m/%y
+--date-format %d/%m/%y
+
+1/1/14 * Test
+ A $10
+ B
+
+12/1/14 * Test
+ A $20
+ B
+
+test --input-date-format %d/%m/%y reg --begin 2/1/13
+01/01/14 Test A $10 $10
+ B $-10 0
+12/01/14 Test A $20 $20
+ B $-20 0
+end test
+
+test --input-date-format %d/%m/%y reg --begin 1/1/14
+01/01/14 Test A $10 $10
+ B $-10 0
+12/01/14 Test A $20 $20
+ B $-20 0
+end test
+
+test --input-date-format %d/%m/%y reg --begin 2/1/14
+12/01/14 Test A $20 $20
+ B $-20 0
+end test
+
diff --git a/test/regress/1074.test b/test/regress/1074.test
new file mode 100644
index 00000000..1aaf0ca0
--- /dev/null
+++ b/test/regress/1074.test
@@ -0,0 +1,161 @@
+
+--input-date-format %Y-%m-%d
+--date-format %Y-%m-%d
+
+2011-06-01 * Jun 2011
+ A $10
+ B
+
+2011-07-01 * Jul 2011
+ A $10
+ B
+
+2011-08-01 * Aug 2011
+ A $10
+ B
+
+2012-06-01 * Jun 2012
+ A $10
+ B
+
+2012-07-01 * Jul 2012
+ A $10
+ B
+
+2012-08-01 * Aug 2012
+ A $10
+ B
+
+2013-06-01 * Jun 2013
+ A $10
+ B
+
+2013-07-01 * Jul 2013
+ A $10
+ B
+
+2013-08-01 * Aug 2013
+ A $10
+ B
+
+2014-06-01 * Jun 2014
+ A $10
+ B
+
+2014-07-01 * Jul 2014
+ A $10
+ B
+
+2014-08-01 * Aug 2014
+ A $10
+ B
+
+2015-06-01 * Jun 2015
+ A $10
+ B
+
+2015-07-01 * Jul 2015
+ A $10
+ B
+
+2015-08-01 * Aug 2015
+ A $10
+ B
+
+test --now 2012-02-03 reg -p "from june to july"
+2012-06-01 Jun 2012 A $10 $10
+ B $-10 0
+end test
+
+test --now 2013-02-03 reg -p "from june to july"
+2013-06-01 Jun 2013 A $10 $10
+ B $-10 0
+end test
+
+test --now 2014-02-03 reg -p "from june to july"
+2014-06-01 Jun 2014 A $10 $10
+ B $-10 0
+end test
+
+test --now 2014-10-02 reg -p "from june to july"
+2014-06-01 Jun 2014 A $10 $10
+ B $-10 0
+end test
+
+test --now 2012-02-03 reg -p "from june to july 2014"
+2012-06-01 Jun 2012 A $10 $10
+ B $-10 0
+2012-07-01 Jul 2012 A $10 $10
+ B $-10 0
+2012-08-01 Aug 2012 A $10 $10
+ B $-10 0
+2013-06-01 Jun 2013 A $10 $10
+ B $-10 0
+2013-07-01 Jul 2013 A $10 $10
+ B $-10 0
+2013-08-01 Aug 2013 A $10 $10
+ B $-10 0
+2014-06-01 Jun 2014 A $10 $10
+ B $-10 0
+end test
+
+test --now 2013-10-02 reg -p "from june to july 2014"
+2013-06-01 Jun 2013 A $10 $10
+ B $-10 0
+2013-07-01 Jul 2013 A $10 $10
+ B $-10 0
+2013-08-01 Aug 2013 A $10 $10
+ B $-10 0
+2014-06-01 Jun 2014 A $10 $10
+ B $-10 0
+end test
+
+test --now 2014-01-02 reg -p "from june to july 2014"
+2014-06-01 Jun 2014 A $10 $10
+ B $-10 0
+end test
+
+test --now 2014-10-02 reg -p "from june to july 2014"
+2014-06-01 Jun 2014 A $10 $10
+ B $-10 0
+end test
+
+test --now 2012-02-03 reg -p "from june 2012 to july 2014"
+2012-06-01 Jun 2012 A $10 $10
+ B $-10 0
+2012-07-01 Jul 2012 A $10 $10
+ B $-10 0
+2012-08-01 Aug 2012 A $10 $10
+ B $-10 0
+2013-06-01 Jun 2013 A $10 $10
+ B $-10 0
+2013-07-01 Jul 2013 A $10 $10
+ B $-10 0
+2013-08-01 Aug 2013 A $10 $10
+ B $-10 0
+2014-06-01 Jun 2014 A $10 $10
+ B $-10 0
+end test
+
+test --now 2012-02-03 reg -p "from june 2013 to july 2014"
+2013-06-01 Jun 2013 A $10 $10
+ B $-10 0
+2013-07-01 Jul 2013 A $10 $10
+ B $-10 0
+2013-08-01 Aug 2013 A $10 $10
+ B $-10 0
+2014-06-01 Jun 2014 A $10 $10
+ B $-10 0
+end test
+
+test --now 2015-02-03 reg -p "from june 2013 to july 2014"
+2013-06-01 Jun 2013 A $10 $10
+ B $-10 0
+2013-07-01 Jul 2013 A $10 $10
+ B $-10 0
+2013-08-01 Aug 2013 A $10 $10
+ B $-10 0
+2014-06-01 Jun 2014 A $10 $10
+ B $-10 0
+end test
+
diff --git a/test/regress/5D92A5EB.test b/test/regress/5D92A5EB.test
index 6d29eda6..57fcadb3 100644
--- a/test/regress/5D92A5EB.test
+++ b/test/regress/5D92A5EB.test
@@ -29,6 +29,6 @@ While parsing periodic transaction:
> Liabilities:Education:ULL $100.00
> Liabilities:Mortgage $100.00
> Assets:Bank:Checking
-Error: Posting with null amount's account may be mispelled:
+Error: Posting with null amount's account may be misspelled:
"Expenses:Entertainment:Blizzard $100.00"
end test
diff --git a/test/regress/730.test b/test/regress/730.test
new file mode 100644
index 00000000..d81a1c22
--- /dev/null
+++ b/test/regress/730.test
@@ -0,0 +1,37 @@
+; Using -M in combination with an empty result causes a segmentation fault
+; therefore this test case does not have or need any test data
+
+test -f /dev/null -M reg
+end test
+
+; Tests mentioned in #730
+test reg -M
+end test
+
+test reg -M .foo
+end test
+
+test reg -M -e 2012/01
+end test
+
+
+; Tests mentioned in #1080
+test reg '^Expenses' and expr 'any(account =~ /^Assets:Cash/)' --period 'every week this month'
+end test
+
+test bal '^Expenses' and expr 'any(account =~ /^Assets:Cash/)' --period 'every week this month'
+end test
+
+test bal reg foo and expr 'any(account =~ /bar/)' --period 'every week'
+end test
+
+
+; Tests mentioned in #1084
+test b abc -M
+end test
+
+test reg foo -M
+end test
+
+test bal foo -M
+end test
diff --git a/test/regress/A013A73B.test b/test/regress/A013A73B.test
new file mode 100644
index 00000000..251277ea
--- /dev/null
+++ b/test/regress/A013A73B.test
@@ -0,0 +1,10 @@
+
+2014-01-01 c ; x
+ a 1
+ b
+
+test reg
+14-Jan-01 c a 1 1
+ b -1 0
+end test
+
diff --git a/tools/prepare-commit-msg b/tools/prepare-commit-msg
new file mode 100755
index 00000000..e103888a
--- /dev/null
+++ b/tools/prepare-commit-msg
@@ -0,0 +1,27 @@
+#!/bin/sh
+#
+# Prepare git commit message:
+# - Add [ci skip] if the changes seem irrelevant for continuous integration
+
+# Add [ci skip] to the commit message unless there are changes to files
+# that are relevant for testing such as src/*, test/*, ledger3.texi, ...
+function add_ci_skip()
+{
+ pattern="$1"; shift
+ if [ $(git diff --cached --name-only | grep --count "$pattern") -eq 0 ]; then
+ tempfile=$(mktemp $0.XXXXXX)
+ cat - "$1" <<EOF > "$tempfile"
+
+# It seems the changes to be committed are irrelevant for the continuous
+# integration, therefore it will be skipped for this commit.
+#
+# If you still want continuous integration to run for this commit
+# comment or remove the next line.
+[ci skip]
+EOF
+ mv "$tempfile" "$1"
+ fi
+}
+
+## MAIN
+add_ci_skip '\(^src\|^test\|^doc/ledger3.texi\|^\.travis.yml\|CMakeLists.txt\)' "$@"
diff --git a/tools/travis-before_install.sh b/tools/travis-before_install.sh
new file mode 100755
index 00000000..a1800021
--- /dev/null
+++ b/tools/travis-before_install.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+#set -x
+set -e
+set -o pipefail
+
+if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
+ brew update
+fi
+
+if [ -n "${BOOST_VERSION}" ]; then
+ echo "Downloading boost ${BOOST_VERSION}"
+ mkdir -p $BOOST_ROOT
+ wget --no-verbose --output-document=- \
+ http://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION}/boost_${BOOST_VERSION//./_}.tar.bz2/download \
+ | tar jxf - --strip-components=1 -C "${BOOST_ROOT}"
+fi
diff --git a/tools/travis-install.sh b/tools/travis-install.sh
new file mode 100755
index 00000000..b5039d5c
--- /dev/null
+++ b/tools/travis-install.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+
+#set -x
+set -e
+set -o pipefail
+
+if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
+ for formula in $(echo "${BREWS//,/ }"); do
+ echo "Checking ${formula} formula"
+ brew outdated "${formula}" \
+ || (brew unlink "${formula}"
+ brew install "${formula}"
+ )
+ done
+fi
+
+if [ -d "${BOOST_ROOT}" ]; then
+ echo "Installing boost ${BOOST_VERSION} in ${BOOST_ROOT}"
+ (cd "${BOOST_ROOT}"
+ ./bootstrap.sh --with-libraries="${BOOST_LIBS}"
+ ./b2 threading=multi --prefix="${BOOST_ROOT}" -d0 install
+ )
+fi