├── VERSION
├── hledger-web
├── config
│ ├── robots.txt
│ ├── favicon.ico
│ ├── keter.yaml
│ ├── settings.yml
│ └── routes
├── messages
│ └── en.msg
├── Setup.hs
├── templates
│ ├── default-layout.hamlet
│ ├── homepage.lucius
│ ├── homepage.julius
│ ├── homepage.hamlet
│ └── default-layout-wrapper.hamlet
├── static
│ ├── favicon.ico
│ ├── select2.png
│ ├── select2-spinner.gif
│ ├── img
│ │ ├── glyphicons-halflings.png
│ │ └── glyphicons-halflings-white.png
│ └── jquery.url.js
├── Handler
│ ├── RootR.hs
│ ├── JournalEditR.hs
│ ├── JournalEntriesR.hs
│ ├── RegisterR.hs
│ ├── JournalR.hs
│ └── Utils.hs
├── .ghci
├── tests
│ ├── TestImport.hs
│ ├── main.hs
│ └── HomeTest.hs
├── Settings
│ ├── Development.hs
│ └── StaticFiles.hs
├── app
│ └── main.hs
├── Hledger
│ ├── Web.hs
│ └── Web
│ │ ├── Options.hs
│ │ └── Main.hs
├── devel.hs
├── Import.hs
├── Application.hs
├── Settings.hs
└── deploy
│ └── Procfile
├── bin
└── README.md
├── hledger
├── Setup.hs
├── hledger-cli.hs
├── tests
│ └── suite.hs
├── hlint.hs
└── Hledger
│ └── Cli
│ ├── Incomestatement.hs
│ ├── Balancesheet.hs
│ ├── Histogram.hs
│ ├── Tests.hs
│ ├── Cashflow.hs
│ ├── Print.hs
│ ├── Version.hs
│ ├── Register.hs
│ └── Stats.hs
├── hledger-lib
├── Setup.hs
├── tests
│ └── suite.hs
├── Hledger.hs
├── Hledger
│ ├── Data.hs
│ ├── Data
│ │ ├── Commodity.hs
│ │ ├── Ledger.hs
│ │ └── FormatStrings.hs
│ ├── Read
│ │ └── TimelogReader.hs
│ └── Utils
│ │ └── UTF8IOCompat.hs
└── hledger-lib.cabal
├── extra
├── hledger-chart
│ ├── Setup.hs
│ ├── hledger-chart.hs
│ ├── Hledger
│ │ ├── Chart.hs
│ │ └── Chart
│ │ │ └── Options.hs
│ └── hledger-chart.cabal
├── hledger-vty
│ ├── Setup.hs
│ ├── hledger-vty.hs
│ ├── Hledger
│ │ ├── Vty.hs
│ │ └── Vty
│ │ │ └── Options.hs
│ └── hledger-vty.cabal
├── README
├── current.journal
├── all.journal
├── accountnames.hs
├── uniquify.hs
├── equity.hs
├── makefile
└── aliases.sh
├── profs
└── README.txt
├── tools
├── trhsx
├── criterionbench.hs
├── progressionbench.hs
├── regressiontest.py
├── dayssincetag.hs
├── unittest.hs
├── simplifyprof.hs
├── runhledgerhpc
├── generatejournal.hs
├── listbydeps.hs
└── doctest.hs
├── site
├── images
│ ├── mac.png
│ ├── linux.png
│ ├── sshot.png
│ ├── windows.png
│ ├── watchhours.png
│ ├── hledger-charts-2.png
│ ├── hledger-screen-1.png
│ └── hledger-web-journal.png
├── js
│ └── highslide
│ │ ├── graphics
│ │ ├── close.png
│ │ ├── icon.gif
│ │ ├── closeX.png
│ │ ├── loader.gif
│ │ ├── resize.gif
│ │ ├── zoomin.cur
│ │ ├── zoomout.cur
│ │ ├── fullexpand.gif
│ │ ├── geckodimmer.png
│ │ ├── loader.white.gif
│ │ └── outlines
│ │ │ ├── beveled.png
│ │ │ ├── drop-shadow.png
│ │ │ ├── glossy-dark.png
│ │ │ ├── outer-glow.png
│ │ │ ├── rounded-black.png
│ │ │ └── rounded-white.png
│ │ └── highslide-ie6.css
├── api-frames.html
├── site.hs
├── templates
│ └── default.html
└── css
│ └── style.css
├── data
├── sample.csv
├── sample.rules
├── sample.timelog
├── unicode.journal
└── sample.journal
├── tests
├── unicode-error-message.test
├── null-accountname-component.test
├── unbalanced.test
├── print-acct-pattern.test
├── unicode-account-matching.test
├── balance-precision.test
├── unicode-print.test
├── eliding-print.test.notimplemented
├── print-desc-pattern.test
├── unicode-balance.test
├── parens-in-account-name.test
├── balance-depth.test
├── decimals-balance-failure.test
├── parse-posting-error-pos.test
├── balance-date2.test
├── parse-blank-description.test
├── print-long-account.test
├── register-date2.test
├── unicode-register.test
├── zero-handling.test
├── eliding-register.test.notimplemented
├── stats.test
├── unicode-description-matching.test
├── timelog-stack-overflow.test
├── no-such-file.test
├── print-date2.test
├── balance-custom-format.test
├── include.test
├── 94.test
├── timezone.test
├── parse-dates.test
├── balance-sample.test
├── commodities.test
├── filter-patterns.test
├── aliases.test
├── balance-eliding.test
├── virtual.test
├── status.test
├── 87-wrong-balance.test
├── register-depth.test
├── timelog.test
├── comments.test
├── parse-ledger-sample.test
├── default-commodity.test
├── register-intervals.test
├── read-csv.test
├── balance-assertions.test
├── tags.test
├── add.test
├── amount-layout-vertical.test
└── precision.test
├── .authorspellings
├── .gitignore
├── DOCS.md
├── bench.tests
├── CSV.md
├── ALIASES.md
├── SCREENSHOTS.md
├── ANNOUNCE
├── README.md
├── HCAR.tex
├── CONTRIBUTORS.md
└── .boring
/VERSION:
--------------------------------------------------------------------------------
1 | 0.21.3
2 |
--------------------------------------------------------------------------------
/hledger-web/config/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 |
--------------------------------------------------------------------------------
/hledger-web/messages/en.msg:
--------------------------------------------------------------------------------
1 | Hello: Hello
2 |
--------------------------------------------------------------------------------
/bin/README.md:
--------------------------------------------------------------------------------
1 | Developer binaries built with the makefile go here.
2 |
--------------------------------------------------------------------------------
/hledger/Setup.hs:
--------------------------------------------------------------------------------
1 | import Distribution.Simple
2 | main = defaultMain
3 |
--------------------------------------------------------------------------------
/hledger-lib/Setup.hs:
--------------------------------------------------------------------------------
1 | import Distribution.Simple
2 | main = defaultMain
3 |
--------------------------------------------------------------------------------
/hledger-web/Setup.hs:
--------------------------------------------------------------------------------
1 | import Distribution.Simple
2 | main = defaultMain
3 |
--------------------------------------------------------------------------------
/extra/hledger-chart/Setup.hs:
--------------------------------------------------------------------------------
1 | import Distribution.Simple
2 | main = defaultMain
3 |
--------------------------------------------------------------------------------
/extra/hledger-vty/Setup.hs:
--------------------------------------------------------------------------------
1 | import Distribution.Simple
2 | main = defaultMain
3 |
--------------------------------------------------------------------------------
/profs/README.txt:
--------------------------------------------------------------------------------
1 | Developer profiling results, benchmark results etc. go here.
2 |
--------------------------------------------------------------------------------
/tools/trhsx:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # fake trhsx, to help "make hledgermac"
3 | cp $2 $3
4 |
--------------------------------------------------------------------------------
/extra/hledger-vty/hledger-vty.hs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env runhaskell
2 | import Hledger.Vty (main)
3 |
--------------------------------------------------------------------------------
/extra/hledger-chart/hledger-chart.hs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env runhaskell
2 | import Hledger.Chart (main)
3 |
--------------------------------------------------------------------------------
/site/images/mac.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/images/mac.png
--------------------------------------------------------------------------------
/data/sample.csv:
--------------------------------------------------------------------------------
1 | "2012/3/22","TRANSFER TO SAVINGS","-10.00"
2 | "2012/3/23","SOMETHING ELSE","5.50"
3 |
--------------------------------------------------------------------------------
/site/images/linux.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/images/linux.png
--------------------------------------------------------------------------------
/site/images/sshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/images/sshot.png
--------------------------------------------------------------------------------
/extra/README:
--------------------------------------------------------------------------------
1 | Extra stuff: less-maintained add-ons, custom report scripts, shell aliases, make rules...
2 |
--------------------------------------------------------------------------------
/extra/current.journal:
--------------------------------------------------------------------------------
1 | ; current/recent years
2 |
3 | ;!include 2010.journal
4 | !include 2011.journal
5 |
--------------------------------------------------------------------------------
/site/images/windows.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/images/windows.png
--------------------------------------------------------------------------------
/hledger-web/templates/default-layout.hamlet:
--------------------------------------------------------------------------------
1 | $maybe msg <- mmsg
2 |
#{msg}
3 | ^{widget}
4 |
--------------------------------------------------------------------------------
/site/images/watchhours.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/images/watchhours.png
--------------------------------------------------------------------------------
/hledger-web/config/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/hledger-web/config/favicon.ico
--------------------------------------------------------------------------------
/hledger-web/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/hledger-web/static/favicon.ico
--------------------------------------------------------------------------------
/hledger-web/static/select2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/hledger-web/static/select2.png
--------------------------------------------------------------------------------
/hledger-web/templates/homepage.lucius:
--------------------------------------------------------------------------------
1 | h1 {
2 | text-align: center
3 | }
4 | h2##{aDomId} {
5 | color: #990
6 | }
7 |
--------------------------------------------------------------------------------
/site/images/hledger-charts-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/images/hledger-charts-2.png
--------------------------------------------------------------------------------
/site/images/hledger-screen-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/images/hledger-screen-1.png
--------------------------------------------------------------------------------
/site/images/hledger-web-journal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/images/hledger-web-journal.png
--------------------------------------------------------------------------------
/site/js/highslide/graphics/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/js/highslide/graphics/close.png
--------------------------------------------------------------------------------
/site/js/highslide/graphics/icon.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/js/highslide/graphics/icon.gif
--------------------------------------------------------------------------------
/hledger-web/static/select2-spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/hledger-web/static/select2-spinner.gif
--------------------------------------------------------------------------------
/site/js/highslide/graphics/closeX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/js/highslide/graphics/closeX.png
--------------------------------------------------------------------------------
/site/js/highslide/graphics/loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/js/highslide/graphics/loader.gif
--------------------------------------------------------------------------------
/site/js/highslide/graphics/resize.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/js/highslide/graphics/resize.gif
--------------------------------------------------------------------------------
/site/js/highslide/graphics/zoomin.cur:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/js/highslide/graphics/zoomin.cur
--------------------------------------------------------------------------------
/site/js/highslide/graphics/zoomout.cur:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/js/highslide/graphics/zoomout.cur
--------------------------------------------------------------------------------
/site/js/highslide/graphics/fullexpand.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/js/highslide/graphics/fullexpand.gif
--------------------------------------------------------------------------------
/site/js/highslide/graphics/geckodimmer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/js/highslide/graphics/geckodimmer.png
--------------------------------------------------------------------------------
/site/js/highslide/graphics/loader.white.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/js/highslide/graphics/loader.white.gif
--------------------------------------------------------------------------------
/hledger-web/static/img/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/hledger-web/static/img/glyphicons-halflings.png
--------------------------------------------------------------------------------
/site/js/highslide/graphics/outlines/beveled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/js/highslide/graphics/outlines/beveled.png
--------------------------------------------------------------------------------
/tests/unicode-error-message.test:
--------------------------------------------------------------------------------
1 | hledgerdev -f - balance
2 | <<<
3 | 2009-01-01 broken entry
4 | дебит 1
5 | кредит -2
6 | >>>2 /дебит/
7 | >>>= 1
8 |
--------------------------------------------------------------------------------
/hledger-web/templates/homepage.julius:
--------------------------------------------------------------------------------
1 | document.getElementById("#{aDomId}").innerHTML = "This text was added by the Javascript part of the homepage widget.";
2 |
--------------------------------------------------------------------------------
/site/js/highslide/graphics/outlines/drop-shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/js/highslide/graphics/outlines/drop-shadow.png
--------------------------------------------------------------------------------
/site/js/highslide/graphics/outlines/glossy-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/js/highslide/graphics/outlines/glossy-dark.png
--------------------------------------------------------------------------------
/site/js/highslide/graphics/outlines/outer-glow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/js/highslide/graphics/outlines/outer-glow.png
--------------------------------------------------------------------------------
/hledger-web/static/img/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/hledger-web/static/img/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/site/js/highslide/graphics/outlines/rounded-black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/js/highslide/graphics/outlines/rounded-black.png
--------------------------------------------------------------------------------
/site/js/highslide/graphics/outlines/rounded-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/batterseapower/hledger/master/site/js/highslide/graphics/outlines/rounded-white.png
--------------------------------------------------------------------------------
/data/sample.rules:
--------------------------------------------------------------------------------
1 | date-field 0
2 | description-field 1
3 | amount-field 2
4 | currency $
5 | base-account assets:bank:checking
6 |
7 | SAVINGS
8 | assets:bank:savings
9 |
--------------------------------------------------------------------------------
/tests/null-accountname-component.test:
--------------------------------------------------------------------------------
1 | # hledgerdev -f - balance -E
2 | # <<<
3 | # 2009/1/1 x
4 | # a: 13
5 | # b
6 | # >>>2 /accountname seems ill-formed: a:/
7 | # >>>= 1
8 |
--------------------------------------------------------------------------------
/tests/unbalanced.test:
--------------------------------------------------------------------------------
1 | hledgerdev -f - register
2 | <<<
3 | 2009/1/1 a
4 | b 1.1
5 | c -1
6 | >>>2 /could not balance this transaction \(real postings are off by 0.1\)/
7 | >>>= 1
8 |
--------------------------------------------------------------------------------
/hledger/hledger-cli.hs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env runhaskell
2 | -- the hledger command-line executable; see Hledger/Cli/Main.hs
3 |
4 | module Main (main)
5 | where
6 | import Hledger.Cli.Main (main)
7 |
--------------------------------------------------------------------------------
/extra/all.journal:
--------------------------------------------------------------------------------
1 | ; all years
2 |
3 | !include 2006.journal
4 | !include 2007.journal
5 | !include 2008.journal
6 | !include 2009.journal
7 | !include 2010.journal
8 | !include 2011.journal
9 |
--------------------------------------------------------------------------------
/data/sample.timelog:
--------------------------------------------------------------------------------
1 | i 2009/03/27 09:00:00 projects:a
2 | o 2009/03/27 17:00:34
3 | i 2009/03/31 22:21:45 personal:reading:online
4 | o 2009/04/01 02:00:34
5 | i 2009/04/02 09:00:00 projects:b
6 | o 2009/04/02 17:00:34
7 |
--------------------------------------------------------------------------------
/tests/print-acct-pattern.test:
--------------------------------------------------------------------------------
1 | # print with negative account pattern should exclude transactions containing a matched posting
2 | hledgerdev -f- print not:a
3 | <<<
4 | 2010/1/1 x
5 | a 1
6 | b -1
7 | >>>
8 | >>>=0
9 |
--------------------------------------------------------------------------------
/hledger-web/Handler/RootR.hs:
--------------------------------------------------------------------------------
1 | -- | Site root and misc. handlers.
2 |
3 | module Handler.RootR where
4 |
5 | import Import
6 |
7 | getRootR :: Handler RepHtml
8 | getRootR = redirect defaultroute where defaultroute = RegisterR
9 |
--------------------------------------------------------------------------------
/hledger-web/.ghci:
--------------------------------------------------------------------------------
1 | :set -i.:config:dist/build/autogen
2 | :set -XCPP -XTemplateHaskell -XQuasiQuotes -XTypeFamilies -XFlexibleContexts -XGADTs -XOverloadedStrings -XMultiParamTypeClasses -XGeneralizedNewtypeDeriving -XEmptyDataDecls
3 |
--------------------------------------------------------------------------------
/tests/unicode-account-matching.test:
--------------------------------------------------------------------------------
1 | hledgerdev -f - register τράπ
2 | <<<
3 | 2009-01-01 проверка
4 | τράπεζα 10 руб
5 | नकद
6 | >>>
7 | 2009/01/01 проверка τράπεζα 10 руб 10 руб
8 | >>>=0
9 |
--------------------------------------------------------------------------------
/tests/balance-precision.test:
--------------------------------------------------------------------------------
1 | #
2 | hledgerdev -f- balance
3 | <<<
4 | 1/1
5 | a 1.00
6 | b -1
7 | >>>
8 | 1.00 a
9 | -1.00 b
10 | --------------------
11 | 0
12 | >>>=0
13 |
--------------------------------------------------------------------------------
/tests/unicode-print.test:
--------------------------------------------------------------------------------
1 | hledgerdev -f - print
2 | <<<
3 | 2009-01-01 проверка
4 | счёт:первый 1
5 | счёт:второй
6 | >>>
7 | 2009/01/01 проверка
8 | счёт:первый 1
9 | счёт:второй -1
10 |
11 | >>>=0
12 |
--------------------------------------------------------------------------------
/hledger-lib/tests/suite.hs:
--------------------------------------------------------------------------------
1 | import Hledger (tests_Hledger)
2 | import Test.Framework.Providers.HUnit (hUnitTestToTests)
3 | import Test.Framework.Runners.Console (defaultMain)
4 |
5 | main :: IO ()
6 | main = defaultMain $ hUnitTestToTests tests_Hledger
7 |
--------------------------------------------------------------------------------
/tests/eliding-print.test.notimplemented:
--------------------------------------------------------------------------------
1 | hledgerdev -f- print
2 | <<<
3 | 2009/1/1 x
4 | aaaaaaaaaaaaaaaaaaaa:aaaaaaaaaaaaaaaaaaaa:aaaaaaaaaaaaaaaaaaaa €1
5 | b
6 | >>>
7 | 2009/01/01 x
8 | aa:aaaaaaaaaa:aaaaaaaaaaaaaaaaaaaa
9 | b
10 |
--------------------------------------------------------------------------------
/tests/print-desc-pattern.test:
--------------------------------------------------------------------------------
1 | hledgerdev -f - print desc:x
2 | <<<
3 | 2009/1/1 x
4 | a 1
5 | b
6 |
7 | 2009/1/1 y
8 | a 1
9 | b
10 |
11 | >>>
12 | 2009/01/01 x
13 | a 1
14 | b -1
15 |
16 | >>>=0
17 |
--------------------------------------------------------------------------------
/tests/unicode-balance.test:
--------------------------------------------------------------------------------
1 | hledgerdev -f - balance
2 | <<<
3 | 2009-01-01 проверка
4 | τράπεζα 10 руб
5 | नकद
6 | >>>
7 | 10 руб τράπεζα
8 | -10 руб नकद
9 | --------------------
10 | 0
11 | >>>=0
12 |
--------------------------------------------------------------------------------
/hledger/tests/suite.hs:
--------------------------------------------------------------------------------
1 | import Hledger.Cli (tests_Hledger_Cli)
2 | import Test.Framework.Providers.HUnit (hUnitTestToTests)
3 | import Test.Framework.Runners.Console (defaultMain)
4 |
5 | main :: IO ()
6 | main = defaultMain $ hUnitTestToTests tests_Hledger_Cli
7 |
--------------------------------------------------------------------------------
/tests/parens-in-account-name.test:
--------------------------------------------------------------------------------
1 | hledgerdev -f - print
2 | <<<
3 | 2009-01-01 x
4 | a 2
5 | b (b) b -1
6 | c
7 | >>>
8 | 2009/01/01 x
9 | a 2
10 | b (b) b -1
11 | c -1
12 |
13 | >>>=0
14 |
--------------------------------------------------------------------------------
/data/unicode.journal:
--------------------------------------------------------------------------------
1 | ; unicode in description, account name and currency symbol
2 | 2010/1/1 ß
3 | (ß) 10 ß
4 |
5 | ; as above but with characters from code pages not installed on a western ms windows machine
6 | 2010/1/1 проверка
7 | (проверка) 10 проверка
8 |
9 |
--------------------------------------------------------------------------------
/extra/accountnames.hs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env runhaskell
2 | -- list the default journal's chart of accounts in --flat style
3 | import Hledger
4 | main = do
5 | j <- myJournal
6 | let l = journalToLedger nullfilterspec{empty=True} j
7 | mapM_ putStrLn (accountnames l)
8 |
--------------------------------------------------------------------------------
/tests/balance-depth.test:
--------------------------------------------------------------------------------
1 | # 1
2 | hledgerdev -f data/sample.journal balance --no-total --depth 1
3 | >>>
4 | $-1 assets
5 | $2 expenses
6 | $-2 income
7 | $1 liabilities
8 | >>>=0
9 |
10 |
--------------------------------------------------------------------------------
/tests/decimals-balance-failure.test:
--------------------------------------------------------------------------------
1 | # b amount with no decimal places, in middle, causes balance failure (0.6.1)
2 | hledgerdev -f - print
3 | <<<
4 | 2009/1/1 x
5 | a $1.25
6 | b $-1
7 | c $-0.25
8 |
9 | >>>2
10 | >>>=0
11 |
--------------------------------------------------------------------------------
/tests/parse-posting-error-pos.test:
--------------------------------------------------------------------------------
1 | # should give an accurate parse error location
2 | # hledgerdev -f- stat
3 | # <<<
4 | # 2010/1/1 x
5 | # a 1
6 | # b
7 |
8 | # 2010/1/1 y
9 | # c: 1
10 | # d
11 |
12 | # >>>2 /line 6, column 5/
13 | # >>>= 1
14 |
--------------------------------------------------------------------------------
/hledger-web/tests/TestImport.hs:
--------------------------------------------------------------------------------
1 | {-# LANGUAGE OverloadedStrings #-}
2 | module TestImport
3 | ( module Yesod.Test
4 | , module Foundation
5 | , Specs
6 | ) where
7 |
8 | import Yesod.Test
9 |
10 | import Foundation
11 |
12 | type Specs = YesodSpec App
13 |
--------------------------------------------------------------------------------
/hledger-web/Settings/Development.hs:
--------------------------------------------------------------------------------
1 | module Settings.Development where
2 |
3 | import Prelude
4 |
5 | development :: Bool
6 | development =
7 | #if DEVELOPMENT
8 | True
9 | #else
10 | False
11 | #endif
12 |
13 | production :: Bool
14 | production = not development
15 |
--------------------------------------------------------------------------------
/tests/balance-date2.test:
--------------------------------------------------------------------------------
1 | hledgerdev -f - balance -p 'in 2009' --date2
2 | <<<
3 | 2009/1/1 x
4 | a 1
5 | b
6 |
7 | 2009/1/1=2010/1/1 x
8 | a 10
9 | b
10 | >>>
11 | 1 a
12 | -1 b
13 | --------------------
14 | 0
15 | >>>=0
16 |
--------------------------------------------------------------------------------
/tests/parse-blank-description.test:
--------------------------------------------------------------------------------
1 | # 1. accept a blank description
2 | hledgerdev -f- print
3 | <<<
4 | 2010/1/1
5 | a 1
6 | b
7 |
8 | >>>=0
9 |
10 | # 2. same, but no separator space after the date
11 | hledgerdev -f- print
12 | <<<
13 | 2010/1/1
14 | a 1
15 | b
16 |
17 | >>>=0
18 |
--------------------------------------------------------------------------------
/.authorspellings:
--------------------------------------------------------------------------------
1 | -- hints for darcs show author
2 | Tim Docker
3 | Nick Ingolia
4 | Marko Kocić
5 | Oliver Braun
6 | Gwern Branwen
7 | Michael Snoyman
8 | Trygve Laugstøl
9 |
--------------------------------------------------------------------------------
/tests/print-long-account.test:
--------------------------------------------------------------------------------
1 | hledgerdev -f - print
2 | <<<
3 | 2009/1/1 x
4 | aaaaabbbbbcccccdddddeeeeefffffggggghhhhh 1
5 | b
6 | >>>
7 | 2009/01/01 x
8 | aaaaabbbbbcccccdddddeeeeefffffggggghhhhh 1
9 | b -1
10 |
11 | >>>=0
12 |
--------------------------------------------------------------------------------
/tests/register-date2.test:
--------------------------------------------------------------------------------
1 | hledgerdev -f - register --date2
2 | <<<
3 | 2009/1/1=2010/1/1 x
4 | a 1
5 | b
6 | >>>
7 | 2010/01/01 x a 1 1
8 | b -1 0
9 | >>>=0
10 |
--------------------------------------------------------------------------------
/tests/unicode-register.test:
--------------------------------------------------------------------------------
1 | hledgerdev -f - register
2 | <<<
3 | 2009-01-01 проверка
4 | τράπεζα 10 руб
5 | नकद
6 | >>>
7 | 2009/01/01 проверка τράπεζα 10 руб 10 руб
8 | नकद -10 руб 0
9 | >>>=0
10 |
--------------------------------------------------------------------------------
/tests/zero-handling.test:
--------------------------------------------------------------------------------
1 | # a zero amount is always displayed as just "0", regardless of any commodity/decimal places/price (like ledger)
2 | #
3 | hledgerdev -f- print --empty
4 | <<<
5 | 2010/3/1 x
6 | a $0.00 @ 3EUR
7 | b
8 | >>>
9 | 2010/03/01 x
10 | a 0
11 | b 0
12 |
13 | >>>=0
14 |
--------------------------------------------------------------------------------
/hledger-web/config/keter.yaml:
--------------------------------------------------------------------------------
1 | exec: ../dist/build/hledger-web/hledger-web
2 | args:
3 | - production
4 | host: <>
5 |
6 | # Use the following to automatically copy your bundle upon creation via `yesod
7 | # keter`. Uses `scp` internally, so you can set it to a remote destination
8 | # copy-to: user@host:/opt/keter/incoming
9 |
--------------------------------------------------------------------------------
/tests/eliding-register.test.notimplemented:
--------------------------------------------------------------------------------
1 | hledgerdev -f- register
2 | <<<
3 | 2009/1/1 x aaaaaaaaaaaaaaaaaaaa:aaaaaaaaaaaaaaaaaaaa:aaaaaaaaaaaaaaaaaaaa €1
4 | b
5 | >>>
6 | 2009/01/01 x aa:aa:aaaaaaaaaaaaaaaa €1 €1
7 | b €-1 0
8 |
--------------------------------------------------------------------------------
/tests/stats.test:
--------------------------------------------------------------------------------
1 | # 1. empty file
2 | hledgerdev -f- stats
3 | <<<
4 | >>> /Accounts.* 0 \(depth 0\)/
5 | >>>=0
6 |
7 | # 2. included files should be listed in parse order
8 | touch a.j b.j; hledgerdev -f- stats; rm -f a.j b.j
9 | <<<
10 | include a.j
11 | include b.j
12 | >>> /Included journal files *: *\.\/a/
13 | >>>2
14 | >>>=0
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.aes
2 | */dist/
3 | *.hi
4 | *.o
5 | _*
6 | cabal-dev*
7 | hledger-web/static/tmp/
8 | hledger-web/yesod-devel/
9 | TAGS
10 | tags
11 | bin/*
12 | site/site
13 | site/*.md
14 | site/[0-9]*
15 | /config
16 | /messages
17 | /static
18 | /templates
19 | profs/profs
20 | t.*
21 | tt.*
22 | ttt.*
23 | tttt.*
24 | ttttt.*
25 | site/api
26 | .haddockprologue
27 |
--------------------------------------------------------------------------------
/hledger-web/config/settings.yml:
--------------------------------------------------------------------------------
1 | Default: &defaults
2 | host: "*4" # any IPv4 host
3 | port: 3000
4 | approot: "http://localhost:3000"
5 | copyright: " "
6 | #analytics: UA-YOURCODE
7 |
8 | Development:
9 | <<: *defaults
10 |
11 | Testing:
12 | <<: *defaults
13 |
14 | Staging:
15 | <<: *defaults
16 |
17 | Production:
18 | #approot: "http://www.example.com"
19 | <<: *defaults
20 |
--------------------------------------------------------------------------------
/tests/unicode-description-matching.test:
--------------------------------------------------------------------------------
1 | hledgerdev -f - register desc:аура
2 | <<<
3 | 2009-01-01 аура (cyrillic letters)
4 | bank 10
5 | cash
6 | 2010-01-01 aypa (roman letters)
7 | bank 20
8 | cash
9 | >>>
10 | 2009/01/01 аура (cyrillic le.. bank 10 10
11 | cash -10 0
12 | >>>=0
13 |
--------------------------------------------------------------------------------
/hledger-web/app/main.hs:
--------------------------------------------------------------------------------
1 | import Prelude (IO)
2 | -- import Yesod.Default.Config (fromArgs)
3 | -- import Yesod.Default.Main (defaultMain)
4 | -- import Settings (parseExtra)
5 | -- import Application (makeApplication)
6 |
7 | import qualified Hledger.Web.Main
8 |
9 | main :: IO ()
10 | -- main = defaultMain (fromArgs parseExtra) makeApplication
11 | main = Hledger.Web.Main.main
12 |
--------------------------------------------------------------------------------
/tests/timelog-stack-overflow.test:
--------------------------------------------------------------------------------
1 | # this gave a stack space overflow error with 0.8-0.9 due to infinite
2 | # recursion in Posting and Transaction's equality tests:
3 | hledgerdev -f - balance
4 | <<<
5 | i 2010/1/1 09:00:00 a:b
6 | o 2010/1/1 09:03:00
7 | >>>=0
8 | # incidentally this didn't trigger it.. go figure
9 | #hledgerdev -f - balance
10 | #<<<
11 | #i 2010/1/1 09:00:00 a:b
12 | #o 2010/1/1 09:02:00
13 | #>>>=0
14 |
--------------------------------------------------------------------------------
/tools/criterionbench.hs:
--------------------------------------------------------------------------------
1 | {- Criterion-based benchmarks. Criterion displays and minimises the impact
2 | of time variance and charts the results. -}
3 |
4 | import Criterion.Main
5 | import System.Environment (withArgs)
6 | import qualified HledgerMain
7 |
8 | main = defaultMain [
9 | bench "balance_100x100x10" $ nfIO $ withArgs ["balance", "-f", "100x100x10.ledger", ">/dev/null"] HledgerMain.main
10 | ]
11 |
--------------------------------------------------------------------------------
/tests/no-such-file.test:
--------------------------------------------------------------------------------
1 | # commands should generally autocreate an empty journal when missing, see also add*.test
2 | # $$ used for safe concurrent test running, may be a bash-ism
3 |
4 | hledgerdev register -f no-such-file-$$; rm -f no-such-file-$$
5 | >>>
6 | >>>2 /journal file.*not found/
7 | >>>=0
8 |
9 | hledgerdev balance --no-total -f no-such-file-$$; rm -f no-such-file-$$
10 | >>>
11 | >>>2 /journal file.*not found/
12 | >>>=0
13 |
--------------------------------------------------------------------------------
/tools/progressionbench.hs:
--------------------------------------------------------------------------------
1 | {- Progression-based benchmarks. Progression charts the difference between successive benchmark runs. -}
2 |
3 | import Criterion.Main hiding (defaultMain, defaultMainWith)
4 | import Progression.Main
5 | import System.Environment (withArgs)
6 | import qualified HledgerMain
7 |
8 | main = defaultMain $
9 | bench "balance_100x100x10" $ nfIO $ withArgs ["balance", "-f", "100x100x10.ledger", ">/dev/null"] HledgerMain.main
10 |
--------------------------------------------------------------------------------
/hledger-web/config/routes:
--------------------------------------------------------------------------------
1 | /static StaticR Static getStatic
2 | /favicon.ico FaviconR GET
3 | /robots.txt RobotsR GET
4 |
5 | / RootR GET
6 |
7 | /journal JournalR GET POST
8 | /journal/entries JournalEntriesR GET POST
9 | /journal/edit JournalEditR GET POST
10 |
11 | /register RegisterR GET POST
12 |
13 | -- /accounts AccountsR GET
14 | -- /api/accounts AccountsJsonR GET
15 |
--------------------------------------------------------------------------------
/hledger-web/Hledger/Web.hs:
--------------------------------------------------------------------------------
1 | {-|
2 | Re-export the modules of the hledger-web program.
3 | -}
4 |
5 | module Hledger.Web (
6 | module Hledger.Web.Options,
7 | module Hledger.Web.Main,
8 | tests_Hledger_Web
9 | )
10 | where
11 | import Test.HUnit
12 |
13 | import Hledger.Web.Options
14 | import Hledger.Web.Main
15 |
16 | tests_Hledger_Web :: Test
17 | tests_Hledger_Web = TestList
18 | [
19 | -- tests_Hledger_Web_Options
20 | -- ,tests_Hledger_Web_Main
21 | ]
22 |
--------------------------------------------------------------------------------
/extra/hledger-vty/Hledger/Vty.hs:
--------------------------------------------------------------------------------
1 | {-|
2 | Re-export the modules of the hledger-vty program.
3 | -}
4 |
5 | module Hledger.Vty (
6 | module Hledger.Vty.Main,
7 | module Hledger.Vty.Options,
8 | tests_Hledger_Vty
9 | )
10 | where
11 | import Test.HUnit
12 |
13 | import Hledger.Vty.Main
14 | import Hledger.Vty.Options
15 |
16 | tests_Hledger_Vty :: Test
17 | tests_Hledger_Vty = TestList
18 | [
19 | -- tests_Hledger_Vty_Main
20 | -- tests_Hledger_Vty_Options
21 | ]
22 |
--------------------------------------------------------------------------------
/hledger-web/Handler/JournalEditR.hs:
--------------------------------------------------------------------------------
1 | -- | /journal/edit handlers.
2 |
3 | module Handler.JournalEditR where
4 |
5 | import Import
6 |
7 | import Handler.Common
8 | import Handler.Post
9 | import Handler.Utils
10 |
11 |
12 | -- | The journal editform, no sidebar.
13 | getJournalEditR :: Handler RepHtml
14 | getJournalEditR = do
15 | vd <- getViewData
16 | defaultLayout $ do
17 | setTitle "hledger-web journal edit form"
18 | toWidget $ editform vd
19 |
20 | postJournalEditR :: Handler RepHtml
21 | postJournalEditR = handlePost
22 |
--------------------------------------------------------------------------------
/tests/print-date2.test:
--------------------------------------------------------------------------------
1 | # print shows both dates. The second's year defaults to the first's.
2 | hledgerdev -f - print --date2
3 | <<<
4 | 2009/1/1=1/2 x
5 | a 1
6 | b
7 | >>>
8 | 2009/01/01=2009/01/02 x
9 | a 1
10 | b -1
11 |
12 | >>>2
13 | >>>= 0
14 |
15 | # Secondary date of 29 Feb on leap year should be valid
16 | hledgerdev -f - print --date2
17 | <<<
18 | 2001/2/27=2000/2/29 x
19 | a 1
20 | b
21 | >>>
22 | 2001/02/27=2000/02/29 x
23 | a 1
24 | b -1
25 |
26 | >>>2
27 | >>>= 0
28 |
--------------------------------------------------------------------------------
/site/api-frames.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 | hledger api docs
6 |
7 |
18 |
19 |
--------------------------------------------------------------------------------
/tests/balance-custom-format.test:
--------------------------------------------------------------------------------
1 | hledgerdev -f data/sample.journal balance --format="%30(account) %-.20(total)"
2 | >>>
3 | assets $-1
4 | bank:saving $1
5 | cash $-2
6 | expenses $2
7 | food $1
8 | supplies $1
9 | income $-2
10 | gifts $-1
11 | salary $-1
12 | liabilities:debts $1
13 | --------------------
14 | 0
15 | >>>= 0
16 |
--------------------------------------------------------------------------------
/extra/hledger-chart/Hledger/Chart.hs:
--------------------------------------------------------------------------------
1 | {-|
2 | Re-export the modules of the hledger-chart program.
3 | -}
4 |
5 | module Hledger.Chart (
6 | module Hledger.Chart.Main,
7 | module Hledger.Chart.Options,
8 | tests_Hledger_Chart
9 | )
10 | where
11 | import Test.HUnit
12 |
13 | import Hledger.Chart.Main
14 | import Hledger.Chart.Options
15 |
16 | tests_Hledger_Chart :: Test
17 | tests_Hledger_Chart = TestList
18 | [
19 | -- tests_Hledger_Chart_Main
20 | -- tests_Hledger_Chart_Options
21 | ]
22 |
--------------------------------------------------------------------------------
/tests/include.test:
--------------------------------------------------------------------------------
1 | # nested includes in subdirectories
2 | mkdir -p b/c/d ; printf '2010/1/1\n (D) 1\n' >b/c/d/d.journal ; printf '2010/1/1\n (C) 1\n!include d/d.journal\n' >b/c/c.journal ; printf '2010/1/1\n (B) 1\n!include c/c.journal\n' >b/b.journal ; printf '2010/1/1\n (A) 1\n!include b/b.journal\n' >a.journal ; hledgerdev -f a.journal print; rm -rf a.journal b
3 | >>>
4 | 2010/01/01
5 | (A) 1
6 |
7 | 2010/01/01
8 | (B) 1
9 |
10 | 2010/01/01
11 | (C) 1
12 |
13 | 2010/01/01
14 | (D) 1
15 |
16 | >>>2
17 | >>>=0
18 |
--------------------------------------------------------------------------------
/tests/94.test:
--------------------------------------------------------------------------------
1 | # issue 94: total balance should be that of top-level accounts, with and without --flat
2 | # 1.
3 | hledgerdev -f - balance
4 | <<<
5 | 1/1
6 | (a) 1
7 |
8 | 1/1
9 | (a:aa) 1
10 | >>>
11 | 2 a
12 | 1 aa
13 | --------------------
14 | 2
15 | >>>= 0
16 |
17 | # 2.
18 | hledgerdev -f - balance --flat
19 | <<<
20 | 1/1
21 | (a) 1
22 |
23 | 1/1
24 | (a:aa) 1
25 | >>>
26 | 2 a
27 | 1 a:aa
28 | --------------------
29 | 2
30 | >>>= 0
31 |
32 |
--------------------------------------------------------------------------------
/tests/timezone.test:
--------------------------------------------------------------------------------
1 | # timezone-related tests
2 | # 1. as in ledger, historical prices may contain a time and timezone.
3 | # hledger ignores them and uses 00:00 local time instead.
4 | # XXX needs --value not --cost
5 | # hledgerdev -f - balance --no-total --cost
6 | # <<<
7 | # P 2011/01/01 00:00:00 A $1
8 | # P 2011/01/01 15:00:00-0100 A $2
9 |
10 | # 2010/12/31
11 | # (20101231) 1 A
12 |
13 | # 2011/1/1
14 | # (20110101) 1 A
15 |
16 | # 2011/1/2
17 | # (20110102) 1 A
18 | # >>>
19 | # 1 A 20101231
20 | # $2 20110101
21 | # $2 20110102
22 | # >>>=0
23 |
--------------------------------------------------------------------------------
/hledger-lib/Hledger.hs:
--------------------------------------------------------------------------------
1 | module Hledger (
2 | module Hledger.Data
3 | ,module Hledger.Query
4 | ,module Hledger.Read
5 | ,module Hledger.Reports
6 | ,module Hledger.Utils
7 | ,tests_Hledger
8 | )
9 | where
10 | import Test.HUnit
11 |
12 | import Hledger.Data
13 | import Hledger.Query
14 | import Hledger.Read hiding (samplejournal)
15 | import Hledger.Reports
16 | import Hledger.Utils
17 |
18 | tests_Hledger = TestList
19 | [
20 | tests_Hledger_Data
21 | ,tests_Hledger_Query
22 | ,tests_Hledger_Read
23 | ,tests_Hledger_Reports
24 | ]
25 |
--------------------------------------------------------------------------------
/hledger-web/tests/main.hs:
--------------------------------------------------------------------------------
1 | {-# LANGUAGE OverloadedStrings #-}
2 | {-# LANGUAGE NoMonomorphismRestriction #-}
3 | {-# OPTIONS_GHC -fno-warn-orphans #-}
4 |
5 | module Main where
6 |
7 | import Import
8 | import Yesod.Default.Config
9 | import Yesod.Test
10 | import Test.Hspec (hspec)
11 | import Application (makeFoundation)
12 |
13 | import HomeTest
14 |
15 | main :: IO ()
16 | main = do
17 | conf <- Yesod.Default.Config.loadConfig $ (configSettings Testing)
18 | { csParseExtra = parseExtra
19 | }
20 | foundation <- makeFoundation conf
21 | hspec $ do
22 | yesodSpec foundation $ do
23 | homeSpecs
24 |
--------------------------------------------------------------------------------
/tests/parse-dates.test:
--------------------------------------------------------------------------------
1 | # invalid dates should be rejected
2 | # 1. valid month and day, but flipped
3 | hledgerdev -f- print
4 | <<<
5 | 2010/31/12 x
6 | a 1
7 | b
8 | >>>2 /bad date/
9 | >>>= 1
10 | # 2. too-large day
11 | hledgerdev -f- print
12 | <<<
13 | 2010/12/32 x
14 | a 1
15 | b
16 | >>>2 /bad date/
17 | >>>= 1
18 | # 3. 29th feb on leap year should be ok
19 | hledgerdev -f- print
20 | <<<
21 | 2000/2/29 x
22 | a 1
23 | b
24 | >>>
25 | 2000/02/29 x
26 | a 1
27 | b -1
28 |
29 | >>>= 0
30 | # 4. 29th feb on non-leap year should fail
31 | hledgerdev -f- print
32 | <<<
33 | 2001/2/29 x
34 | a 1
35 | b
36 | >>>2 /bad date/
37 | >>>= 1
38 |
--------------------------------------------------------------------------------
/extra/uniquify.hs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env runhaskell
2 | {-|
3 | Uniquify journal entries based on some id in the description. Reads the
4 | default or specified journal, or stdin.
5 |
6 | Usage: uniquify.hs [-f JOURNALFILE | -f-]
7 | |-}
8 |
9 | import Data.List
10 | import Hledger
11 | import Hledger.Cli
12 |
13 | main = do
14 | opts <- getHledgerOpts
15 | withJournalDo opts uniquifyAndPrint
16 |
17 | uniquifyAndPrint :: CliOpts -> Journal -> IO ()
18 | uniquifyAndPrint opts j@Journal{jtxns=ts} = print' opts j{jtxns=uniquify ts}
19 | where
20 | uniquify = nubBy (\t1 t2 -> extractId (tdescription t1) == extractId (tdescription t2))
21 | extractId desc = desc -- extract some part that's supposed to be unique
22 |
--------------------------------------------------------------------------------
/data/sample.journal:
--------------------------------------------------------------------------------
1 | ; A sample journal file.
2 | ;
3 | ; Sets up this account tree:
4 | ; assets
5 | ; bank
6 | ; checking
7 | ; saving
8 | ; cash
9 | ; expenses
10 | ; food
11 | ; supplies
12 | ; income
13 | ; gifts
14 | ; salary
15 | ; liabilities
16 | ; debts
17 |
18 | 2008/01/01 income
19 | assets:bank:checking $1
20 | income:salary
21 |
22 | 2008/06/01 gift
23 | assets:bank:checking $1
24 | income:gifts
25 |
26 | 2008/06/02 save
27 | assets:bank:saving $1
28 | assets:bank:checking
29 |
30 | 2008/06/03 * eat & shop
31 | expenses:food $1
32 | expenses:supplies $1
33 | assets:cash
34 |
35 | 2008/12/31 * pay off
36 | liabilities:debts $1
37 | assets:bank:checking
38 |
39 |
40 | ;final comment
41 |
--------------------------------------------------------------------------------
/hledger-web/tests/HomeTest.hs:
--------------------------------------------------------------------------------
1 | {-# LANGUAGE OverloadedStrings #-}
2 | module HomeTest
3 | ( homeSpecs
4 | ) where
5 |
6 | import TestImport
7 |
8 | homeSpecs :: Specs
9 | homeSpecs =
10 | ydescribe "Some hledger-web tests" $
11 |
12 | yit "serves a reasonable-looking register page" $ do
13 | get RegisterR
14 | statusIs 200
15 | bodyContains "accounts"
16 |
17 | -- post "/" $ do
18 | -- addNonce
19 | -- fileByLabel "Choose a file" "tests/main.hs" "text/plain" -- talk about self-reference
20 | -- byLabel "What's on the file?" "Some Content"
21 |
22 | -- statusIs 200
23 | -- htmlCount ".message" 1
24 | -- htmlAllContain ".message" "Some Content"
25 | -- htmlAllContain ".message" "text/plain"
26 |
--------------------------------------------------------------------------------
/hledger/hlint.hs:
--------------------------------------------------------------------------------
1 | {-
2 | hlint configuration for hledger
3 |
4 | manual: http://community.haskell.org/~ndm/darcs/hlint/hlint.htm
5 |
6 | examples:
7 | ignore "Eta reduce" = "" - suppress all eta reduction suggestions.
8 | ignore "Eta reduce" = Data.List Prelude - suppress eta reduction hints in the Prelude and Data.List modules.
9 | ignore = Data.List.map - don't give any hints in the function Data.List.map.
10 | error = Data.List.map - any hint in the function is an error.
11 | error "Use concatMap" = "" - the hint to use concatMap is an error.
12 | warn "Use concatMap" = "" - the hint to use concatMap is a warning.
13 |
14 | -}
15 |
16 | import HLint.Default
17 | ignore "Use camelCase" = ""
18 |
--------------------------------------------------------------------------------
/tests/balance-sample.test:
--------------------------------------------------------------------------------
1 | # 1.
2 | hledgerdev -f data/sample.journal balance
3 | >>>
4 | $-1 assets
5 | $1 bank:saving
6 | $-2 cash
7 | $2 expenses
8 | $1 food
9 | $1 supplies
10 | $-2 income
11 | $-1 gifts
12 | $-1 salary
13 | $1 liabilities:debts
14 | --------------------
15 | 0
16 | >>>=0
17 |
18 | # 2.
19 | hledgerdev -f data/sample.journal balance o
20 | >>>
21 | $1 expenses:food
22 | $-2 income
23 | $-1 gifts
24 | $-1 salary
25 | --------------------
26 | $-1
27 | >>>=0
28 |
29 |
--------------------------------------------------------------------------------
/tests/commodities.test:
--------------------------------------------------------------------------------
1 | # a commodity may contain/end with numbers, if double quoted
2 | # 1. without quotes, fail. XXX parse error should be clearer here
3 | hledgerdev -f- print
4 | <<<
5 | 2010-04-05 x
6 | a 10 DE0002635307
7 | b
8 | >>>2 /unexpected "0"/
9 | >>>= 1
10 | # 2. with quotes, ok; quotes appear in print output
11 | hledgerdev -f- print
12 | <<<
13 | 2010-04-05 x
14 | a 10 "DE 0002 635307"
15 | b
16 | >>>
17 | 2010/04/05 x
18 | a 10 "DE 0002 635307"
19 | b -10 "DE 0002 635307"
20 |
21 | >>>=0
22 |
23 | # 3. and in other reports too, I guess
24 | hledgerdev -f- balance
25 | <<<
26 | 2010-04-05 x
27 | a 10 "DE0002635307"
28 | b
29 | >>>
30 | 10 "DE0002635307" a
31 | -10 "DE0002635307" b
32 | --------------------
33 | 0
34 | >>>=0
35 |
--------------------------------------------------------------------------------
/hledger-web/devel.hs:
--------------------------------------------------------------------------------
1 | {-# LANGUAGE PackageImports #-}
2 | import "hledger-web" Application (getApplicationDev)
3 | import Network.Wai.Handler.Warp (runSettings, defaultSettings, settingsPort)
4 | import Control.Concurrent (forkIO)
5 | import System.Directory (doesFileExist, removeFile)
6 | import System.Exit (exitSuccess)
7 | import Control.Concurrent (threadDelay)
8 |
9 | main :: IO ()
10 | main = do
11 | putStrLn "Starting devel application"
12 | (port, app) <- getApplicationDev
13 | forkIO $
14 | runSettings defaultSettings
15 | { settingsPort = port
16 | } app
17 | loop
18 |
19 | loop :: IO ()
20 | loop = do
21 | threadDelay 100000
22 | e <- doesFileExist "yesod-devel/devel-terminate"
23 | if e then terminateDevel else loop
24 |
25 | terminateDevel :: IO ()
26 | terminateDevel = exitSuccess
27 |
--------------------------------------------------------------------------------
/extra/equity.hs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env runhaskell
2 | {-
3 | Print an entry posting the total balance of the specified account and
4 | subaccounts, or all accounts, from the default journal. Like ledger's
5 | equity command. Useful when starting a new journal or closing the books.
6 |
7 | Usage: equity.hs [ACCTPAT]
8 | -}
9 | import Hledger
10 | import Hledger.Cli
11 | import System.Environment
12 |
13 | main = do
14 | j <- myJournal
15 | d <- getCurrentDay
16 | args <- getArgs
17 | let acctpat = head $ args ++ [""]
18 | (acctbals,_) = balanceReport [Flat] (optsToFilterSpec [] [acctpat] d) j
19 | txn = nulltransaction{
20 | tdate=d,
21 | tpostings=[nullposting{paccount=a,pamount=b} | (a,_,_,b) <- acctbals]
22 | ++ [nullposting{paccount="equity:opening balances",pamount=missingamt}]}
23 | putStr $ show txn
24 |
--------------------------------------------------------------------------------
/tools/regressiontest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # test whether hledger output matches ledger's
3 | # Simon Michael 2007
4 |
5 | from os import *
6 | from posix import *
7 |
8 | files = [
9 | 'data/test.dat',
10 | 'data/test1.dat',
11 | # getenv('LEDGER'),
12 | ]
13 |
14 | commands = [
15 | 'balance petty',
16 | '-s balance',
17 | '-s balance cash',
18 | 'register',
19 | 'register cash',
20 | 'print',
21 | ]
22 |
23 | do = system
24 | rule = lambda s: "="*30 + s + "="*30
25 |
26 | def regtest(file, cmd):
27 | """Print a heading and the diff of ledger and hledger output. No diff
28 | output is good."""
29 | print rule('%s:%s' % (file,cmd))
30 | putenv('LEDGER',file)
31 | do('ledger %s >1; ./hledger.hs %s >2; diff 1 2' % (cmd,cmd))
32 |
33 | for f in files:
34 | for c in commands:
35 | regtest(f,c)
36 |
37 |
--------------------------------------------------------------------------------
/tools/dayssincetag.hs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env runhaskell
2 | {-
3 | Display the current darcs repository's last tag and the number of days since.
4 | Similar to:
5 | $ darcs changes --to-tag . --from-tag .|head -n 1 |cut -d' ' -f-7 |xargs -I {} date -d "{}" +%s |xargs -I {} expr \( $(date +%s) - {} \) / 60 / 60 / 24
6 | -}
7 | import Data.Time
8 | import System.Environment
9 | import System.Locale
10 | import System.Process
11 |
12 | main = do
13 | tag:_ <- getArgs
14 | s <- readProcess "darcs" ["changes","--from-tag",tag,"--to-tag",tag] ""
15 | let datestr = unwords $ take 6 $ words $ head $ lines s
16 | date = readTime defaultTimeLocale "%a %b %e %H:%M:%S %Z %Y" datestr :: Day
17 | today <- getCurrentDay
18 | putStrLn $ show (diffDays today date) ++ " days since tag "++tag++":\n"
19 | putStr s
20 |
21 | getCurrentDay = do
22 | t <- getZonedTime
23 | return $ localDay (zonedTimeToLocalTime t)
24 |
--------------------------------------------------------------------------------
/tests/filter-patterns.test:
--------------------------------------------------------------------------------
1 | # 1. account pattern with space
2 | hledgerdev -f- register 'a a'
3 | <<<
4 | 2010/3/1 x
5 | a a 1
6 | b
7 | >>>
8 | 2010/03/01 x a a 1 1
9 | >>>=0
10 |
11 | #
12 | # 2. description pattern with space
13 | hledgerdev -f- register desc:'x x'
14 | <<<
15 | 2010/3/1 x
16 | a 1
17 | b
18 |
19 | 2010/3/2 x x
20 | a 1
21 | b
22 | >>>
23 | 2010/03/02 x x a 1 1
24 | b -1 0
25 | >>>=0
26 |
27 | #
28 | # 3. multiple patterns, spaced and punctuated patterns
29 | hledgerdev -f- register 'a a' "'b"
30 | <<<
31 | 2011/9/11
32 | a a 1
33 | 'b
34 | >>>
35 | 2011/09/11 a a 1 1
36 | 'b -1 0
37 | >>>=0
38 |
--------------------------------------------------------------------------------
/DOCS.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: hledger docs
3 | ---
4 |
5 | # Docs
6 |
7 | **Official hledger docs:**
8 |
9 | [Installation Guide](INSTALL.html)\
10 | [Release Notes](NEWS.html)\
11 | **[User Manual](MANUAL.html)** (and past versions:
12 | [0.20](0.20/MANUAL.html),
13 | [0.19](0.19/MANUAL.html),
14 | [0.18](0.18/MANUAL.html))\
15 | [Developer Guide](DEVELOP.html)\
16 | [FAQ](FAQ.html)\
17 |
18 |
19 | **Tutorials:**
20 |
21 | [How to read CSV files](CSV.html)\
22 | [How to use account aliases](ALIASES.html)\
23 |
24 |
25 | **More docs:**
26 |
27 | [hledger.org/wiki](http://hledger.org/wiki)
28 |
29 | **Related:**
30 |
31 | [Accounting For Dragons](http://podcastle.org/2009/10/09/pc-miniature-38-accounting-for-dragons) *informative!*\
32 | [ledger](http://ledger-cli.org) and its [manual](http://ledger-cli.org/3.0/doc/ledger3.html) *explanatory!*\
33 | [beancount](http://furius.ca/beancount/),
34 | [penny](https://github.com/massysett/penny),
35 | [UMM](http://hackage.haskell.org/package/UMM)
36 | *more ledger-likes!*\
37 |
38 |
--------------------------------------------------------------------------------
/bench.tests:
--------------------------------------------------------------------------------
1 | # tests for "make benchmark"
2 | # one command per line, without the executable
3 |
4 | -f data/100x100x10.journal balance
5 | -f data/1000x1000x10.journal balance
6 | #-f data/1000x10000x10.journal balance
7 | -f data/10000x1000x10.journal balance
8 | -f data/10000x1000x10.journal balance aa
9 | #-f data/10000x10000x10.journal balance
10 | #-f data/100000x1000x10.journal balance
11 |
12 | -f data/100x100x10.journal register
13 | -f data/1000x1000x10.journal register
14 | #-f data/1000x10000x10.journal register
15 | #-f data/10000x1000x10.journal register
16 | #-f data/10000x10000x10.journal register
17 | #-f data/10000x1000x10.journal register aa
18 | #-f data/100000x1000x10.journal register
19 |
20 | -f data/100x100x10.journal print
21 | -f data/1000x1000x10.journal print
22 | #-f data/1000x10000x10.journal print
23 | -f data/10000x1000x10.journal print
24 | #-f data/10000x10000x10.journal print
25 | #-f data/10000x1000x10.journal print aa
26 | #-f data/100000x1000x10.journal print
27 |
--------------------------------------------------------------------------------
/tools/unittest.hs:
--------------------------------------------------------------------------------
1 | {-
2 | A standalone unit test runner using test-framework. Compared to hledger's
3 | built-in test runner, this one shows verbose ansi-colored hierarchic
4 | results, can run tests in parallel, and may have better quickcheck support.
5 | -}
6 |
7 | import Test.Framework (defaultMain {-, testGroup-})
8 | import Test.Framework.Providers.HUnit (hUnitTestToTests)
9 | --import Test.Framework.Providers.QuickCheck2 (testProperty)
10 | import Test.HUnit hiding (Test)
11 | import qualified Test.HUnit (Test)
12 | --import Test.QuickCheck
13 | import Tests (tests)
14 | import System.Exit (-- exitFailure, exitWith,
15 | ExitCode(..))
16 | import System.IO (hGetContents, hPutStr, hFlush, stderr, stdout)
17 | import Text.Printf (printf)
18 | --import Text.ParserCombinators.Parsec
19 | import Control.Monad (liftM,when)
20 | import Data.Maybe (fromMaybe)
21 | import System.Process (runInteractiveCommand, waitForProcess)
22 |
23 | main :: IO ()
24 | main = defaultMain $ concatMap hUnitTestToTests tests
25 |
--------------------------------------------------------------------------------
/tests/aliases.test:
--------------------------------------------------------------------------------
1 | # alias-related tests
2 |
3 | # 1. command-line --alias option. Note multiple applicable aliases, but
4 | # only one is applied per account name. Spaces are allowed if quoted.
5 | hledgerdev -f- print --alias 'a a=A' --alias b=B
6 | <<<
7 | 2011/01/01
8 | a a 1
9 | c
10 |
11 | >>>
12 | 2011/01/01
13 | A 1
14 | c -1
15 |
16 | >>>=0
17 |
18 | # 2. alias directive, and an account with unbalanced posting indicators.
19 | hledgerdev -f- print
20 | <<<
21 | alias b=B
22 |
23 | 2011/01/01
24 | (b) 1
25 |
26 | >>>
27 | 2011/01/01
28 | (B) 1
29 |
30 | >>>=0
31 |
32 | # 3. --alias options run after alias directives. Subaccounts are also
33 | # matched and rewritten. Accounts with an internal part matching the alias
34 | # are ignored.
35 | hledgerdev -f- print --alias a=A --alias B=C
36 | <<<
37 | alias a=B
38 |
39 | 2011/01/01
40 | [a:x] 1
41 | [x:a:x]
42 |
43 | >>>
44 | 2011/01/01
45 | [C:x] 1
46 | [x:a:x] -1
47 |
48 | >>>2
49 | >>>=0
50 |
--------------------------------------------------------------------------------
/tests/balance-eliding.test:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env shelltest
2 | # 1. One commodity. Zero accounts should be elided but the final total should not.
3 | hledgerdev -f - balance
4 | <<<
5 | 2010/04/01 tr1
6 | a 16$
7 | b -16$
8 |
9 | 2010/04/02 tr2
10 | a -16$
11 | b 16$
12 | >>>
13 | --------------------
14 | 0
15 | >>>=0
16 |
17 | # 2. An uninteresting parent account (with same balance as its single subaccount) is elided by default, like ledger
18 | hledgerdev -f - balance --no-total
19 | <<<
20 | 1/1
21 | (a:b) 1
22 | >>>
23 | 1 a:b
24 | >>>=0
25 |
26 | # 3. But not with --no-elide
27 | hledgerdev -f - balance --no-total --no-elide
28 | <<<
29 | 1/1
30 | (a:b) 1
31 | >>>
32 | 1 a
33 | 1 b
34 | >>>=0
35 |
36 | # 4. Nor when it has more than one subaccount
37 | hledgerdev -f - balance --no-total
38 | <<<
39 | 1/1
40 | (a:b) 1
41 | (a:c) -1
42 | >>>
43 | 0 a
44 | 1 b
45 | -1 c
46 | >>>2
47 | >>>=0
48 |
49 |
--------------------------------------------------------------------------------
/hledger-web/Import.hs:
--------------------------------------------------------------------------------
1 | module Import
2 | ( module Import
3 | ) where
4 |
5 | import Prelude as Import hiding (head, init, last,
6 | readFile, tail, writeFile)
7 | import Yesod as Import hiding (Route (..))
8 |
9 | import Control.Applicative as Import (pure, (<$>), (<*>))
10 | import Data.Text as Import (Text)
11 |
12 | import Foundation as Import
13 | import Settings as Import
14 | import Settings.Development as Import
15 | import Settings.StaticFiles as Import
16 |
17 | #if __GLASGOW_HASKELL__ >= 704
18 | import Data.Monoid as Import
19 | (Monoid (mappend, mempty, mconcat),
20 | (<>))
21 | #else
22 | import Data.Monoid as Import
23 | (Monoid (mappend, mempty, mconcat))
24 |
25 | infixr 5 <>
26 | (<>) :: Monoid m => m -> m -> m
27 | (<>) = mappend
28 | #endif
29 |
--------------------------------------------------------------------------------
/tools/simplifyprof.hs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env runhaskell
2 | -- simplifyprof.hs somefile.prof
3 | -- filter uninteresting fields from GHC profile output
4 | -- tested with GHC 6.8
5 | -- Simon Michael 2007,2008
6 |
7 | import Data.List
8 | import System.Environment
9 | import Text.Printf
10 |
11 | main = do
12 | args <- getArgs
13 | let f = head args
14 | s <- readFile f
15 | let ls = lines s
16 | let (firstpart, secondpart) = break ("individual inherited" `isInfixOf`) ls
17 | putStr $ unlines firstpart
18 | let fields = map getfields $ filter (not . null) $ drop 2 secondpart
19 | let maxnamelen = maximum $ map (length . head) fields
20 | let fmt = "%-" ++ show maxnamelen ++ "s %10s %5s %6s %9s %10s"
21 | putStrLn $ showheading fmt
22 | putStr $ unlines $ map (format fmt) fields
23 |
24 | getfields s = name:rest
25 | where
26 | space = takeWhile (==' ') s
27 | fields = words s
28 | name = space ++ head fields
29 | rest = drop 3 fields
30 |
31 | showheading fmt = format fmt ["cost centre","entries","%time","%alloc","%time-inh","%alloc-inh"]
32 |
33 | format fmt (s1:s2:s3:s4:s5:s6:[]) = printf fmt s1 s2 s3 s4 s5 s6
34 |
--------------------------------------------------------------------------------
/tests/virtual.test:
--------------------------------------------------------------------------------
1 | # 1. virtual posting shouldn't affect balance
2 | hledgerdev -f- print
3 | <<<
4 | 2009/1/1 x
5 | (virtual) 100
6 | a 1
7 | b
8 | >>>=0
9 | #
10 | # 2. balanced virtual postings should be required to balance (themselves)
11 | hledgerdev -f- print
12 | <<<
13 | 2010/1/1 x
14 | [balanced virtual] 10
15 | a 1
16 | b
17 | >>>= !0
18 | #
19 | # 3. balanced virtual postings should be required to balance (themselves)
20 | hledgerdev -f- print
21 | <<<
22 | 2010/1/1 x
23 | [balanced virtual] 10
24 | [balanced virtual] -10
25 | a 1
26 | b
27 | >>>=0
28 | #
29 | # 4. a virtual posting with implicit amount should be handled correctly
30 | hledgerdev -f- print
31 | <<<
32 | 2010/1/1 x
33 | [a] 10
34 | [b]
35 | >>>=0
36 | #
37 | # 5. real and balanced virtual postings are balanced separately, and multiple blank virtuals are ok
38 | hledgerdev -f- balance
39 | <<<
40 | 2010/1/1 x
41 | a 1
42 | b
43 | [e] 10
44 | [f]
45 | (c)
46 | (d)
47 | >>>
48 | 1 a
49 | -1 b
50 | 10 e
51 | -10 f
52 | --------------------
53 | 0
54 | >>>=0
55 |
--------------------------------------------------------------------------------
/tools/runhledgerhpc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # runhledgerhpc "HPCCOMMAND [HPCARGS]" [HLEDGERARGS]
3 | #
4 | # A front-end that resets the tix count, runs hledgerhpc with the
5 | # specified hledger args, and runs hpc with the specified hpc args.
6 | # Should be run from hledger's top source directory.
7 | #
8 | # Eg:
9 | # hledger$ tools/runhledgerhpc report test
10 | # hledger$ tools/runhledgerhpc "markup --destdir=coverage" test 'some unit test'
11 |
12 | hledgerhpc="hledgerhpc"
13 | verbosity = 0 # 0=no output, 1=stderr only, 2=stdout+stderr
14 |
15 | import sys, os
16 |
17 | hpcargs, hledgerargs = sys.argv[1], ' '.join(sys.argv[2:])
18 |
19 | # remove old tix files
20 | os.system("rm -f %s.tix" % hledgerhpc)
21 |
22 | # run the hpc-enabled binary with the specified hledger arguments to generate tix files
23 | if verbosity<1:
24 | os.system("bin/%s %s >/dev/null 2>&1" % (hledgerhpc,hledgerargs))
25 | elif verbosity==1:
26 | os.system("bin/%s %s >/dev/null" % (hledgerhpc,hledgerargs))
27 | else:
28 | os.system("bin/%s %s" % (hledgerhpc,hledgerargs))
29 |
30 | # run the specified hpc command on the tix files
31 | os.system("hpc %s %s" % (hpcargs,hledgerhpc))
32 |
--------------------------------------------------------------------------------
/hledger-web/Settings/StaticFiles.hs:
--------------------------------------------------------------------------------
1 | module Settings.StaticFiles where
2 |
3 | import Prelude (IO, putStrLn, (++), (>>), return)
4 | import System.IO (stdout, hFlush)
5 | import Yesod.Static
6 | import qualified Yesod.Static as Static
7 | import Settings (staticDir)
8 | import Settings.Development
9 |
10 | -- | use this to create your static file serving site
11 | -- staticSite :: IO Static.Static
12 | -- staticSite = if development then Static.staticDevel staticDir
13 | -- else Static.static staticDir
14 | --
15 | -- | This generates easy references to files in the static directory at compile time,
16 | -- giving you compile-time verification that referenced files exist.
17 | -- Warning: any files added to your static directory during run-time can't be
18 | -- accessed this way. You'll have to use their FilePath or URL to access them.
19 | -- $(staticFiles Settings.staticDir)
20 |
21 |
22 | staticSite :: IO Static.Static
23 | staticSite =
24 | if development
25 | then (do
26 | putStrLn ("Using web files from: " ++ staticDir ++ "/") >> hFlush stdout
27 | Static.staticDevel staticDir)
28 | else (do
29 | -- putStrLn "Using built-in web files" >> hFlush stdout
30 | return $(Static.embed staticDir))
31 |
32 | $(publicFiles staticDir)
33 |
--------------------------------------------------------------------------------
/hledger-web/Handler/JournalEntriesR.hs:
--------------------------------------------------------------------------------
1 | -- | /journal/entries handlers.
2 |
3 | module Handler.JournalEntriesR where
4 |
5 | import Import
6 |
7 | import Handler.Common
8 | import Handler.Post
9 | import Handler.Utils
10 |
11 | import Hledger.Data
12 | import Hledger.Query
13 | import Hledger.Reports
14 | import Hledger.Cli.Options
15 | import Hledger.Web.Options
16 |
17 |
18 | -- | The journal entries view, with sidebar.
19 | getJournalEntriesR :: Handler RepHtml
20 | getJournalEntriesR = do
21 | vd@VD{..} <- getViewData
22 | staticRootUrl <- (staticRoot . settings) <$> getYesod
23 | let
24 | sidecontent = sidebar vd
25 | title = "Journal entries" ++ if m /= Any then ", filtered" else "" :: String
26 | maincontent = entriesReportAsHtml opts vd $ entriesReport (reportopts_ $ cliopts_ opts) Any $ filterJournalTransactions m j
27 | defaultLayout $ do
28 | setTitle "hledger-web journal"
29 | toWidget [hamlet|
30 | ^{topbar vd}
31 |
32 |
33 | ^{sidecontent}
34 |
35 |
36 |
#{title}
37 | ^{searchform vd}
38 | ^{maincontent}
39 | ^{addform staticRootUrl vd}
40 | ^{editform vd}
41 | ^{importform}
42 | |]
43 |
44 | postJournalEntriesR :: Handler RepHtml
45 | postJournalEntriesR = handlePost
46 |
47 |
--------------------------------------------------------------------------------
/hledger/Hledger/Cli/Incomestatement.hs:
--------------------------------------------------------------------------------
1 | {-# LANGUAGE QuasiQuotes, TemplateHaskell, OverloadedStrings, NoCPP #-}
2 | {-|
3 |
4 | The @incomestatement@ command prints a simple income statement (profit & loss) report.
5 |
6 | -}
7 |
8 | module Hledger.Cli.Incomestatement (
9 | incomestatement
10 | ,tests_Hledger_Cli_Incomestatement
11 | ) where
12 |
13 | import qualified Data.Text.Lazy.IO as LT
14 | import Test.HUnit
15 | import Text.Shakespeare.Text
16 |
17 | import Hledger
18 | import Hledger.Cli.Options
19 | import Hledger.Cli.Balance
20 |
21 | -- | Print a simple income statement.
22 | incomestatement :: CliOpts -> Journal -> IO ()
23 | incomestatement CliOpts{reportopts_=ropts} j = do
24 | d <- getCurrentDay
25 | let q = queryFromOpts d ropts
26 | incomereport@(_,income) = accountsReport ropts (And [q, journalIncomeAccountQuery j]) j
27 | expensereport@(_,expenses) = accountsReport ropts (And [q, journalExpenseAccountQuery j]) j
28 | total = income + expenses
29 | LT.putStr $ [lt|Income Statement
30 |
31 | Revenues:
32 | #{unlines $ accountsReportAsText ropts incomereport}
33 | Expenses:
34 | #{unlines $ accountsReportAsText ropts expensereport}
35 |
36 | Total:
37 | --------------------
38 | #{padleft 20 $ showMixedAmountWithoutPrice total}
39 | |]
40 |
41 | tests_Hledger_Cli_Incomestatement :: Test
42 | tests_Hledger_Cli_Incomestatement = TestList
43 | [
44 | ]
45 |
--------------------------------------------------------------------------------
/tests/status.test:
--------------------------------------------------------------------------------
1 | # filtering by transaction status
2 |
3 | # 1. with --cleared, print shows cleared transactions only
4 | hledgerdev -f- print --cleared
5 | <<<
6 | 2010/1/1 x
7 | a 1
8 | b
9 |
10 | 2010/1/2 * x
11 | a 1
12 | b
13 |
14 | 2010/1/3 *
15 | a 1
16 | b
17 | >>>
18 | 2010/01/02 * x
19 | a 1
20 | b -1
21 |
22 | 2010/01/03 *
23 | a 1
24 | b -1
25 |
26 | >>>=0
27 |
28 | # 2. with --uncleared, shows uncleared transactions only
29 | hledgerdev -f- print --uncleared
30 | <<<
31 | 2010/1/1 x
32 | a 1
33 | b
34 |
35 | 2010/1/2 * x
36 | a 1
37 | b
38 |
39 | 2010/1/3 *
40 | a 1
41 | b
42 | >>>
43 | 2010/01/01 x
44 | a 1
45 | b -1
46 |
47 | >>>=0
48 |
49 | # 2. can also have per-posting cleared status
50 | hledgerdev -f- register --cleared
51 | <<<
52 | 2012/1/1
53 | a 1
54 | *b 2
55 | * c 4
56 | d
57 | >>>
58 | 2012/01/01 b 2 2
59 | c 4 6
60 | >>>= 0
61 |
62 |
63 | # 3. also works with balance as shown, same as ledger. Hmm.
64 | hledgerdev -f- balance --uncleared
65 | <<<
66 | 2012/1/1
67 | a 1
68 | *b 2
69 | d
70 |
71 | >>>
72 | 1 a
73 | -3 d
74 | --------------------
75 | -2
76 | >>>=0
77 |
--------------------------------------------------------------------------------
/CSV.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: hledger How to read CSV files
3 | ---
4 |
5 | # How to read CSV files
6 |
7 | Here's a quick example of [converting a CSV file](MANUAL.html#csv-files).
8 |
9 | Say we have downloaded `checking.csv` from a bank for the first time:
10 |
11 | "Date","Note","Amount"
12 | "2012/3/22","DEPOSIT","50.00"
13 | "2012/3/23","TRANSFER TO SAVINGS","-10.00"
14 |
15 | We could create `checking.csv.rules` containing:
16 |
17 | account1 assets:bank:checking
18 | skip 1
19 | fields date, description, amount
20 | currency $
21 |
22 | if ~ SAVINGS
23 | account2 assets:bank:savings
24 |
25 | This says:
26 | "always use assets:bank:checking as the first account;
27 | ignore the first line;
28 | use the first, second and third CSV fields as the entry date, description and amount respectively;
29 | always prepend $ to the amount value;
30 | if the CSV record contains 'SAVINGS', use assets:bank:savings as the second account".
31 | [CSV files](MANUAL.html#csv-files) in the manual describes the syntax.
32 |
33 | Now hledger can read this CSV file:
34 |
35 | $ hledger -f checking.csv print
36 | using conversion rules file checking.csv.rules
37 | 2012/03/22 DEPOSIT
38 | income:unknown $-50.00
39 | assets:bank:checking $50.00
40 |
41 | 2012/03/23 TRANSFER TO SAVINGS
42 | assets:bank:savings $10.00
43 | assets:bank:checking $-10.00
44 |
45 | We might save this output as `checking.journal`, and/or merge it (manually) into the main journal file.
46 |
47 |
--------------------------------------------------------------------------------
/hledger-web/Handler/RegisterR.hs:
--------------------------------------------------------------------------------
1 | -- | /register handlers.
2 |
3 | module Handler.RegisterR where
4 |
5 | import Import
6 |
7 | import Data.Maybe
8 |
9 | import Handler.Common
10 | import Handler.Post
11 | import Handler.Utils
12 |
13 | import Hledger.Query
14 | import Hledger.Reports
15 | import Hledger.Cli.Options
16 | import Hledger.Web.Options
17 |
18 | -- | The main journal/account register view, with accounts sidebar.
19 | getRegisterR :: Handler RepHtml
20 | getRegisterR = do
21 | vd@VD{..} <- getViewData
22 | staticRootUrl <- (staticRoot . settings) <$> getYesod
23 | let sidecontent = sidebar vd
24 | -- injournal = isNothing inacct
25 | filtering = m /= Any
26 | title = "Transactions in "++a++s1++s2
27 | where
28 | (a,inclsubs) = fromMaybe ("all accounts",False) $ inAccount qopts
29 | s1 = if inclsubs then " (and subaccounts)" else ""
30 | s2 = if filtering then ", filtered" else ""
31 | maincontent = registerReportHtml opts vd $ accountTransactionsReport (reportopts_ $ cliopts_ opts) j m $ fromMaybe Any $ inAccountQuery qopts
32 | defaultLayout $ do
33 | setTitle "hledger-web register"
34 | toWidget [hamlet|
35 | ^{topbar vd}
36 |
37 |
38 | ^{sidecontent}
39 |
40 |
41 |
#{title}
42 | ^{searchform vd}
43 | ^{maincontent}
44 | ^{addform staticRootUrl vd}
45 | ^{editform vd}
46 | ^{importform}
47 | |]
48 |
49 | postRegisterR :: Handler RepHtml
50 | postRegisterR = handlePost
51 |
--------------------------------------------------------------------------------
/tests/87-wrong-balance.test:
--------------------------------------------------------------------------------
1 | # 1. issue 87, hledger should give this balance.
2 | hledgerdev -f - balance --no-total b
3 | <<<
4 | 1/1
5 | a -553.653 X @@ 2609.92
6 | a -5.684 X @@ 26.10
7 | a -50.833 X @@ 234.90
8 | a -49.714 X @@ 234.90
9 | a -49.957 X @@ 234.90
10 | a -49.778 X @@ 234.90
11 | a -142.316 X @@ 674.01
12 | a -49.029 X @@ 234.90
13 | a -51.233 X @@ 234.90
14 | a -49.204 X @@ 234.90
15 | a -49.474 X @@ 234.90
16 | a -47.773 X @@ 234.90
17 | a -109.439 X @@ 576.96
18 | a -31.133 X @@ 171.51
19 | a -438.249 X @@ 2537.90
20 | a -11.927 X @@ 72.03
21 | a -170.721 X @@ 990.18
22 | a 1910.117 X @@ 10742.52
23 | b
24 | >>>
25 | -969.81 b
26 | >>>= 0
27 |
28 | # 2. As above, but the prices have a commodity - should work the same.
29 | hledgerdev -f - balance --no-total b
30 | <<<
31 | 1/1
32 | a -553.653 X @@ 2609.92 Y
33 | a -5.684 X @@ 26.10 Y
34 | a -50.833 X @@ 234.90 Y
35 | a -49.714 X @@ 234.90 Y
36 | a -49.957 X @@ 234.90 Y
37 | a -49.778 X @@ 234.90 Y
38 | a -142.316 X @@ 674.01 Y
39 | a -49.029 X @@ 234.90 Y
40 | a -51.233 X @@ 234.90 Y
41 | a -49.204 X @@ 234.90 Y
42 | a -49.474 X @@ 234.90 Y
43 | a -47.773 X @@ 234.90 Y
44 | a -109.439 X @@ 576.96 Y
45 | a -31.133 X @@ 171.51 Y
46 | a -438.249 X @@ 2537.90 Y
47 | a -11.927 X @@ 72.03 Y
48 | a -170.721 X @@ 990.18 Y
49 | a 1910.117 X @@ 10742.52 Y
50 | b
51 | >>>
52 | -969.81 Y b
53 | >>>= 0
54 |
--------------------------------------------------------------------------------
/tests/register-depth.test:
--------------------------------------------------------------------------------
1 | # 1. register --depth N matches postings as usual but clips account names to N
2 | hledgerdev -f - register aa --depth 1
3 | <<<
4 | 2010/1/1 x
5 | a:aa:aaa 1
6 | b
7 | >>>
8 | 2010/01/01 x a 1 1
9 | >>>=0
10 |
11 | # 2. similar to above, postings with same clipped account name are not aggregated
12 | hledgerdev -f - register aa --depth 2
13 | <<<
14 | 2010/1/1 x
15 | a:aa 1
16 | b:bb:bbb
17 |
18 | 2010/1/1 y
19 | a:aa 1
20 | b:bb:bbb
21 |
22 | 2010/1/2 z
23 | a:aa 1
24 | b:bb:bbb
25 | >>>
26 | 2010/01/01 x a:aa 1 1
27 | 2010/01/01 y a:aa 1 2
28 | 2010/01/02 z a:aa 1 3
29 | >>>=0
30 |
31 | # 3. as above, but with a reporting interval causing postings to be aggregated
32 | hledgerdev -f - register aa --depth 1 --daily
33 | <<<
34 | 2010/1/1 x
35 | a:aa 1
36 | b:bb:bbb
37 |
38 | 2010/1/1 y
39 | a:aa 1
40 | b:bb:bbb
41 |
42 | 2010/1/2 z
43 | a:aa 1
44 | b:bb:bbb
45 | >>>
46 | 2010/01/01 - 2010/01/01 a 2 2
47 | 2010/01/02 - 2010/01/02 a 1 3
48 | >>>=0
49 |
50 | # 4. with --cleared
51 | hledgerdev -f - register a --depth 1 --cleared
52 | <<<
53 | 2012/1/1 *
54 | (a:aa) 1
55 | >>>
56 | 2012/01/01 (a) 1 1
57 | >>>2
58 | >>>=0
59 |
--------------------------------------------------------------------------------
/hledger/Hledger/Cli/Balancesheet.hs:
--------------------------------------------------------------------------------
1 | {-# LANGUAGE QuasiQuotes, RecordWildCards, NoCPP #-}
2 | {-|
3 |
4 | The @balancesheet@ command prints a simple balance sheet.
5 |
6 | -}
7 |
8 | module Hledger.Cli.Balancesheet (
9 | balancesheet
10 | ,tests_Hledger_Cli_Balancesheet
11 | ) where
12 |
13 | import qualified Data.Text.Lazy.IO as LT
14 | import Test.HUnit
15 | import Text.Shakespeare.Text
16 |
17 | import Hledger
18 | import Hledger.Cli.Options
19 | import Hledger.Cli.Balance
20 |
21 |
22 | -- | Print a simple balance sheet.
23 | balancesheet :: CliOpts -> Journal -> IO ()
24 | balancesheet CliOpts{reportopts_=ropts} j = do
25 | -- let lines = case formatFromOpts ropts of Left err, Right ...
26 | d <- getCurrentDay
27 | let q = queryFromOpts d (withoutBeginDate ropts)
28 | assetreport@(_,assets) = accountsReport ropts (And [q, journalAssetAccountQuery j]) j
29 | liabilityreport@(_,liabilities) = accountsReport ropts (And [q, journalLiabilityAccountQuery j]) j
30 | total = assets + liabilities
31 | LT.putStr $ [lt|Balance Sheet
32 |
33 | Assets:
34 | #{unlines $ accountsReportAsText ropts assetreport}
35 | Liabilities:
36 | #{unlines $ accountsReportAsText ropts liabilityreport}
37 |
38 | Total:
39 | --------------------
40 | #{padleft 20 $ showMixedAmountWithoutPrice total}
41 | |]
42 |
43 | withoutBeginDate :: ReportOpts -> ReportOpts
44 | withoutBeginDate ropts@ReportOpts{..} = ropts{begin_=Nothing, period_=p}
45 | where p = case period_ of Nothing -> Nothing
46 | Just (i, DateSpan _ e) -> Just (i, DateSpan Nothing e)
47 |
48 | tests_Hledger_Cli_Balancesheet = TestList
49 | [
50 | ]
51 |
--------------------------------------------------------------------------------
/ALIASES.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: hledger How to use account aliases
3 | ---
4 |
5 | # How to use account aliases
6 |
7 | Here's an example of using [account aliases](MANUAL.html#account-aliases).
8 |
9 | Say a sole proprietor has a personal.journal:
10 |
11 | 1/1
12 | expenses:food $1
13 | assets:cash
14 |
15 | and a business.journal:
16 |
17 | 1/1
18 | expenses:office supplies $1
19 | assets:business checking
20 |
21 | Here each entity has a simple journal with its own simple chart of
22 | accounts. But at tax reporting time, we need to view these as a single
23 | entity. So in unified.journal we adjust the personal account names to fit
24 | within the business chart of accounts:
25 |
26 | alias expenses = equity:draw:personal
27 | alias assets:cash = assets:personal cash
28 | include personal.journal
29 | end aliases
30 | include business.journal
31 |
32 | giving:
33 |
34 | $ hledger -f unified.journal print
35 | 2011/01/01
36 | equity:draw:personal:food $1
37 | assets:personal cash $-1
38 |
39 | 2011/01/01
40 | expenses:office supplies $1
41 | assets:business checking $-1
42 |
43 | You can also specify aliases on the command line. This could be useful to
44 | rewrite account names when sharing a report with someone else, such as
45 | your accountant:
46 |
47 | $ hledger --alias 'my earning=income:business'
48 |
49 | Command-line alias options are applied after any alias directives in the
50 | journal. At most one alias directive and one alias option will be applied
51 | to each account name.
52 |
53 |
--------------------------------------------------------------------------------
/tests/timelog.test:
--------------------------------------------------------------------------------
1 | # a timelog session is parsed as a similarly-named transaction with one virtual posting
2 | hledgerdev -f - print
3 | <<<
4 | i 2009/1/1 08:00:00 something
5 | o 2009/1/1 09:00:00
6 |
7 | >>>
8 | 2009/01/01 * 08:00-09:00
9 | (something) 1.0h
10 |
11 | >>>2
12 | >>>= 0
13 |
14 | # ledger timelog example from #ledger
15 | # ==== consulting.timelog
16 | # ; Timelog for consulting sideline
17 | # ; All times UTC
18 | # i 2011/01/26 16:00:00 XXXX:Remote "IPMI Access"
19 | # o 2011/01/26 16:15:00
20 |
21 | # i 2011/01/26 17:45:00 XXXX:Onsite "Fix opty server"
22 | # o 2011/01/26 20:00:00
23 |
24 | # i 2011/01/27 18:00:00 XXXX:Remote "SSL certificate for www.YYYY.com"
25 | # o 2011/01/27 18:15:00
26 |
27 | # ; vim:ts=2 sw=2 sts=2 et ft=ledger fdm=manual:
28 | # ==== consulting.dat
29 | # ; Ledger for Consulting sideline
30 |
31 | # !account Consulting
32 | # !include consulting.timelog
33 | # !end
34 |
35 |
36 | # 2010/02/27 (INV#2) XXXX Test Invoice
37 | # Consulting:XXXX:Remote -0.5h @ $75.00
38 | # Consulting:XXXX:Onsite -2.25h @ $100.00
39 | # Receivable:Consulting:XXXX
40 |
41 |
42 | # ; vim:ts=2 sw=2 sts=2 et ft=ledger fdm=manual:
43 | # ==== command: ledger -f consulting.dat -s bal
44 | # -2.25h Consulting:XXXX:Onsite
45 | # 2.25h Consulting:XXXX:Onsite "Fix opty server"
46 | # -30.0m Consulting:XXXX:Remote
47 | # 15.0m Consulting:XXXX:Remote "IPMI Access"
48 | # 15.0m Consulting:XXXX:Remote "SSL certificate for www.YYYY.com"
49 | # $262.5 Receivable:Consulting:XXXX
50 | # --------------------
51 | # $262.5
52 |
--------------------------------------------------------------------------------
/extra/makefile:
--------------------------------------------------------------------------------
1 | # some hledger-related make scripts
2 |
3 | HLEDGER=hledger
4 |
5 | YEAR:=$(shell date +%Y)
6 | MONTH:=$(shell date +%m)
7 | MONTHS:=$(shell ghc -e "(putStr . unwords . map show) [1..$(MONTH)]")
8 | MONTHS2:=$(shell ghc -e "(putStr . unwords . map show) [2..$(MONTH)]")
9 |
10 | ###############################################################################
11 |
12 | # convert latest bank csv downloads to journal files
13 | BANKJOURNALS = \
14 | mint.journal \
15 | WellsFargoChecking1.journal \
16 | WellsFargoSavings2.journal \
17 | WellsFargoSavings3.journal \
18 | WellsFargoCreditCard4.journal \
19 | Paypal.journal
20 | convert-csv: move-csv $(BANKJOURNALS)
21 |
22 | # move and rename any newly downloaded bank csv files
23 | DOWNLOADDIR=~/Desktop
24 | move-csv:
25 | @(F=$(DOWNLOADDIR)/transactions.csv; [ -e $$F ] && (mv $$F mint.csv; echo new mint.csv found) || exit 0)
26 | @(F=$(DOWNLOADDIR)/Checking1.csv; [ -e $$F ] && (mv $$F WellsFargoChecking1.csv; echo new WellsFargoChecking1.csv found) || exit 0)
27 | @(F=$(DOWNLOADDIR)/Savings2.csv; [ -e $$F ] && (mv $$F WellsFargoSavings2.csv; echo new WellsFargoSavings2.csv found) || exit 0)
28 | @(F=$(DOWNLOADDIR)/Savings3.csv; [ -e $$F ] && (mv $$F WellsFargoSavings3.csv; echo new WellsFargoSavings3.csv found) || exit 0)
29 | @(F=$(DOWNLOADDIR)/CreditCard4.csv; [ -e $$F ] && (mv $$F WellsFargoCreditCard4.csv; echo new WellsFargoCreditCard4.csv found) || exit 0)
30 | @(F=$(DOWNLOADDIR)/Download.csv; [ -e $$F ] && (mv $$F Paypal.csv; echo new Paypal.csv found) || exit 0)
31 |
32 | # convert a csv to a journal using the similarly named rules file
33 | %.journal: %.csv %.rules
34 | $(HLEDGER) convert $< >$@
35 |
36 | %.rules:
37 | touch '$@'
38 |
39 |
--------------------------------------------------------------------------------
/hledger-web/Handler/JournalR.hs:
--------------------------------------------------------------------------------
1 | -- | /journal handlers.
2 |
3 | module Handler.JournalR where
4 |
5 | import Import
6 |
7 | import Handler.Common
8 | import Handler.Post
9 | import Handler.Utils
10 |
11 | import Hledger.Query
12 | import Hledger.Reports
13 | import Hledger.Cli.Options
14 | import Hledger.Web.Options
15 |
16 | -- | The formatted journal view, with sidebar.
17 | getJournalR :: Handler RepHtml
18 | getJournalR = do
19 | vd@VD{..} <- getViewData
20 | staticRootUrl <- (staticRoot . settings) <$> getYesod
21 | let sidecontent = sidebar vd
22 | -- XXX like registerReportAsHtml
23 | inacct = inAccount qopts
24 | -- injournal = isNothing inacct
25 | filtering = m /= Any
26 | -- showlastcolumn = if injournal && not filtering then False else True
27 | title = case inacct of
28 | Nothing -> "Journal"++s2
29 | Just (a,inclsubs) -> "Transactions in "++a++s1++s2
30 | where s1 = if inclsubs then " (and subaccounts)" else ""
31 | where
32 | s2 = if filtering then ", filtered" else ""
33 | maincontent = journalTransactionsReportAsHtml opts vd $ journalTransactionsReport (reportopts_ $ cliopts_ opts) j m
34 | defaultLayout $ do
35 | setTitle "hledger-web journal"
36 | toWidget [hamlet|
37 | ^{topbar vd}
38 |
39 |
40 | ^{sidecontent}
41 |
42 |
43 |
#{title}
44 | ^{searchform vd}
45 | ^{maincontent}
46 | ^{addform staticRootUrl vd}
47 | ^{editform vd}
48 | ^{importform}
49 | |]
50 |
51 | postJournalR :: Handler RepHtml
52 | postJournalR = handlePost
53 |
54 |
--------------------------------------------------------------------------------
/tests/comments.test:
--------------------------------------------------------------------------------
1 | # comment tests
2 |
3 | # 1.
4 | hledgerdev -f - print
5 | <<<
6 | 2009/01/01 x
7 | ; transaction comment 1
8 | ; transaction comment 2
9 | a 1
10 | b
11 | >>>
12 | 2009/01/01 x
13 | ; transaction comment 1
14 | ; transaction comment 2
15 | a 1
16 | b -1
17 |
18 | >>>=0
19 |
20 | # 2.
21 | hledgerdev -f - print
22 | <<<
23 | 2009/01/01 x
24 | a 1
25 | b
26 | ; comment line after postings
27 | >>>
28 | 2009/01/01 x
29 | a 1
30 | b -1
31 |
32 | >>>=0
33 |
34 | # 3. print should preserve comments
35 | hledgerdev -f - print
36 | <<<
37 | ; isolated journal comment
38 |
39 | ; pre-transaction journal comment
40 | 2009/1/1 x ; transaction comment
41 | a 1 ; posting 1 comment
42 | ; posting 1 comment 2
43 | b
44 | ; posting 2 comment
45 | ; post-transaction journal comment
46 | >>>
47 | 2009/01/01 x ; transaction comment
48 | a 1
49 | ; posting 1 comment
50 | ; posting 1 comment 2
51 | b -1 ; posting 2 comment
52 |
53 | >>>2
54 | >>>=0
55 |
56 | # 4. a posting comment should appear in print
57 | hledgerdev -f - print
58 | <<<
59 | 2010/01/01 x
60 | a 1 ; comment
61 | b -1
62 |
63 | >>>
64 | 2010/01/01 x
65 | a 1 ; comment
66 | b -1
67 |
68 | >>>2
69 | >>>=0
70 |
71 | # 5. a posting comment should not appear in register
72 | hledgerdev -f - register
73 | <<<
74 | 2010/1/1 x
75 | a 1 ; comment
76 | b
77 |
78 | >>>
79 | 2010/01/01 x a 1 1
80 | b -1 0
81 | >>>2
82 | >>>=0
83 |
--------------------------------------------------------------------------------
/site/site.hs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env runhaskell
2 | {-# LANGUAGE OverloadedStrings #-}
3 | import Control.Applicative ((<$>))
4 | import Data.Monoid (mappend)
5 | import Hakyll
6 |
7 | import Control.Monad
8 | import Data.List
9 | import System.Directory
10 | import System.Process
11 | import Text.Pandoc.Options
12 | import Text.Printf
13 |
14 | main = do
15 | symlinkPagesFromParentDir
16 | symlinkIndexHtml
17 | symlinkProfsDir
18 | hakyll $ do
19 | match ("images/*" .||. "js/**" .||. "robots.txt") $ do
20 | route idRoute
21 | compile copyFileCompiler
22 | match "css/*" $ do
23 | route idRoute
24 | compile compressCssCompiler
25 | match "templates/*" $ compile templateCompiler
26 | match ("*.md" .||. "0.20/*.md" .||. "0.19/*.md" .||. "0.18/*.md") $ do
27 | route $ setExtension "html"
28 | compile $
29 | pandocCompilerWith
30 | def
31 | def{writerTableOfContents=True
32 | ,writerTOCDepth=4
33 | ,writerStandalone=True
34 | ,writerTemplate="
$toc$
\n$body$"
35 | }
36 | >>= loadAndApplyTemplate "templates/default.html" defaultContext
37 | >>= relativizeUrls
38 |
39 | symlinkPagesFromParentDir = do
40 | fs <- filter (".md" `isSuffixOf`) `fmap` getDirectoryContents ".."
41 | forM_ fs $ \f -> system $ printf "[ -f %s ] || ln -s ../%s" f f
42 |
43 | symlinkIndexHtml = ensureSiteDir >> system "ln -sf README.html _site/index.html"
44 |
45 | symlinkProfsDir = ensureSiteDir >> system "ln -sf ../../profs _site/profs"
46 |
47 | ensureSiteDir = system "mkdir -p _site"
48 |
49 |
50 |
--------------------------------------------------------------------------------
/tests/parse-ledger-sample.test:
--------------------------------------------------------------------------------
1 | # can we parse this sample journal from c++ ledger source
2 | hledgerdev -f- stats
3 | <<<
4 | ; -*- ledger -*-
5 |
6 | N $
7 |
8 | = /^Expenses:Books/
9 | (Liabilities:Taxes) -0.10
10 |
11 | ~ Monthly
12 | Assets:Bank:Checking $500.00
13 | Income:Salary
14 |
15 | ~ Yearly
16 | Expenses:Donations $100.00
17 | Assets:Bank:Checking
18 |
19 | 2004/05/01 * Checking balance
20 | Assets:Bank:Checking $1,000.00
21 | Equity:Opening Balances
22 |
23 | 2004/05/03=2004/05/01 * Investment balance
24 | Assets:Brokerage 50 AAPL @ $30.00
25 | Equity:Opening Balances
26 |
27 | 2004/05/14 * Páy dày
28 | Assets:Bank:Checking 500.00€
29 | Income:Salary
30 |
31 | 2004/05/14 * Another dày in which there is Páying
32 | Asséts:Bánk:Chécking:Asséts:Bánk:Chécking $500.00
33 | Income:Salary
34 |
35 | 2004/05/14 * Another dày in which there is Páying
36 | Русский язык:Активы:Русский язык:Русский язык $1000.00
37 | Income:Salary
38 |
39 | tag foo
40 |
41 | 2004/05/27 Book Store
42 | Expenses:Books $20.00
43 | Expenses:Cards $40.00
44 | Expenses:Docs $30.00
45 | Liabilities:MasterCard
46 |
47 | end tag
48 |
49 | 2004/05/27 (100) Credit card company
50 | ; This is an xact note!
51 | ; Sample: Value
52 | Liabilities:MasterCard $20.00
53 | ; This is a posting note!
54 | ; Sample: Another Value
55 | ; :MyTag:
56 | Assets:Bank:Checking
57 | ; :AnotherTag:
58 | >>>= 0
59 |
--------------------------------------------------------------------------------
/SCREENSHOTS.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: hledger screenshots
3 | ---
4 |
5 | # Screenshots
6 |
7 |
8 | Click to enlarge, or mouse over for captions..
9 |
10 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/tests/default-commodity.test:
--------------------------------------------------------------------------------
1 | # a default commodity defined with the D directive will be used for any
2 | # commodity-less amounts in subsequent transactions.
3 |
4 | # 1. no default commodity
5 | hledgerdev -f- print
6 | <<<
7 | 2010/1/1
8 | a 1000
9 | b
10 | >>>
11 | 2010/01/01
12 | a 1000
13 | b -1000
14 |
15 | >>>=0
16 |
17 | # 2. pound, two decimal places, no digit group separator
18 | hledgerdev -f- print
19 | <<<
20 | D £1000.00
21 | 2010/1/1
22 | a 1000
23 | b
24 | >>>
25 | 2010/01/01
26 | a £1000.00
27 | b £-1000.00
28 |
29 | >>>=0
30 |
31 | # 3. dollar, comma decimal point, three decimal places, no digit group separator
32 | hledgerdev -f- print
33 | <<<
34 | D $1,000
35 | 2010/1/1
36 | a 1000
37 | b
38 | >>>
39 | 2010/01/01
40 | a $1000,000
41 | b $-1000,000
42 |
43 | >>>=0
44 |
45 | # 4. dollar, three digit group separator, one decimal place
46 | hledgerdev -f- print
47 | <<<
48 | D $1,000.0
49 | 2010/1/1
50 | (a) 1000000
51 | >>>
52 | 2010/01/01
53 | (a) $1,000,000.0
54 |
55 | >>>=0
56 |
57 | # 5. as above, sets the commodity of the commodityless amount, but an
58 | # earlier explicit dollar amount sets the display settings for dollar
59 | hledgerdev -f- print
60 | <<<
61 | D $1,000.0
62 | 2010/1/1
63 | (a) $1000000.00
64 | (b) 1000000
65 | >>>
66 | 2010/01/01
67 | (a) $1000000.00
68 | (b) $1000000.00
69 |
70 | >>>=0
71 |
72 | # 6. as above, but the commodityless amount is earliest, so it sets the
73 | # display settings for dollar. The greatest precision is preserved though.
74 | hledgerdev -f- print
75 | <<<
76 | D $1,000.0
77 | 2010/1/1
78 | (a) 1000000
79 | (b) $1000000.00
80 | >>>
81 | 2010/01/01
82 | (a) $1,000,000.00
83 | (b) $1,000,000.00
84 |
85 | >>>=0
86 |
87 |
--------------------------------------------------------------------------------
/hledger-lib/Hledger/Data.hs:
--------------------------------------------------------------------------------
1 | {-|
2 |
3 | The Hledger.Data library allows parsing and querying of C++ ledger-style
4 | journal files. It generally provides a compatible subset of C++ ledger's
5 | functionality. This package re-exports all the Hledger.Data.* modules
6 | (except UTF8, which requires an explicit import.)
7 |
8 | -}
9 |
10 | module Hledger.Data (
11 | module Hledger.Data.Account,
12 | module Hledger.Data.AccountName,
13 | module Hledger.Data.Amount,
14 | module Hledger.Data.Commodity,
15 | module Hledger.Data.Dates,
16 | module Hledger.Data.Journal,
17 | module Hledger.Data.Ledger,
18 | module Hledger.Data.Posting,
19 | module Hledger.Data.TimeLog,
20 | module Hledger.Data.Transaction,
21 | module Hledger.Data.Types,
22 | tests_Hledger_Data
23 | )
24 | where
25 | import Test.HUnit
26 |
27 | import Hledger.Data.Account
28 | import Hledger.Data.AccountName
29 | import Hledger.Data.Amount
30 | import Hledger.Data.Commodity
31 | import Hledger.Data.Dates
32 | import Hledger.Data.Journal
33 | import Hledger.Data.Ledger
34 | import Hledger.Data.Posting
35 | import Hledger.Data.TimeLog
36 | import Hledger.Data.Transaction
37 | import Hledger.Data.Types
38 |
39 | tests_Hledger_Data = TestList
40 | [
41 | tests_Hledger_Data_Account
42 | ,tests_Hledger_Data_AccountName
43 | ,tests_Hledger_Data_Amount
44 | ,tests_Hledger_Data_Commodity
45 | ,tests_Hledger_Data_Dates
46 | ,tests_Hledger_Data_Journal
47 | ,tests_Hledger_Data_Ledger
48 | ,tests_Hledger_Data_Posting
49 | ,tests_Hledger_Data_TimeLog
50 | ,tests_Hledger_Data_Transaction
51 | -- ,tests_Hledger_Data_Types
52 | ]
53 |
--------------------------------------------------------------------------------
/hledger/Hledger/Cli/Histogram.hs:
--------------------------------------------------------------------------------
1 | {-|
2 |
3 | Print a histogram report.
4 |
5 | -}
6 |
7 | module Hledger.Cli.Histogram
8 | where
9 | import Data.List
10 | import Data.Maybe
11 | import Data.Ord
12 | import Text.Printf
13 |
14 | import Hledger.Cli.Options
15 | import Hledger.Data
16 | import Hledger.Reports
17 | import Hledger.Query
18 | import Prelude hiding (putStr)
19 | import Hledger.Utils.UTF8IOCompat (putStr)
20 |
21 |
22 | barchar = '*'
23 |
24 | -- | Print a histogram of some statistic per reporting interval, such as
25 | -- number of postings per day.
26 | histogram :: CliOpts -> Journal -> IO ()
27 | histogram CliOpts{reportopts_=ropts} j = do
28 | d <- getCurrentDay
29 | putStr $ showHistogram ropts (queryFromOpts d ropts) j
30 |
31 | showHistogram :: ReportOpts -> Query -> Journal -> String
32 | showHistogram opts q j = concatMap (printDayWith countBar) spanps
33 | where
34 | i = intervalFromOpts opts
35 | interval | i == NoInterval = Days 1
36 | | otherwise = i
37 | span = queryDateSpan (date2_ opts) q `orDatesFrom` journalDateSpan j
38 | spans = filter (DateSpan Nothing Nothing /=) $ splitSpan interval span
39 | spanps = [(s, filter (isPostingInDateSpan s) ps) | s <- spans]
40 | -- same as Register
41 | -- should count transactions, not postings ?
42 | -- ps = sortBy (comparing postingDate) $ filterempties $ filter matchapats $ filterdepth $ journalPostings j
43 | ps = sortBy (comparing postingDate) $ filterempties $ filter (q `matchesPosting`) $ journalPostings j
44 | filterempties
45 | | queryEmpty q = id
46 | | otherwise = filter (not . isZeroMixedAmount . pamount)
47 |
48 | printDayWith f (DateSpan b _, ts) = printf "%s %s\n" (show $ fromJust b) (f ts)
49 |
50 | countBar ps = replicate (length ps) barchar
51 |
--------------------------------------------------------------------------------
/ANNOUNCE:
--------------------------------------------------------------------------------
1 | I'm pleased to announce hledger and hledger-web 0.21!
2 |
3 | hledger is a command-line tool and haskell library for tracking
4 | financial transactions, which are stored in a human-readable plain
5 | text format. In addition to reporting, it can also help you record new
6 | transactions, or convert CSV data from your bank. Add-on packages
7 | include hledger-web (providing a web interface), hledger-irr and hledger-interest.
8 |
9 | hledger is inspired by and compatible with John Wiegley's Ledger. For
10 | more, see http://hledger.org .
11 |
12 | Install it:
13 |
14 | cabal update; cabal install hledger [hledger-web]
15 |
16 | For more installation help, see http://hledger.org/MANUAL.html#installing .
17 | Or, sponsor a ready-to-run binary for your platform: http://hledger.org/DOWNLOAD.html .
18 |
19 | Release notes (http://hledger.org/NEWS.html#hledger-0.21):
20 |
21 | **Bugs fixed:**
22 |
23 | - parsing: don't fail when a csv amount has trailing whitespace (fixes #113)
24 | - web: don't show prices in the accounts sidebar (fixes #114)
25 | - web: show one line per commodity in charts. Needs more polish, but fixes #109.
26 | - web: bump yesod-platform dependency to avoid a cabal install failure
27 |
28 | **Journal reading:**
29 |
30 | - balance assertions are now checked after reading a journal
31 |
32 | **web command:**
33 |
34 | - web: support/require yesod 1.2
35 | - web: show zero-balance accounts in the sidebar (fixes #106)
36 | - web: use nicer select2 autocomplete widgets in the add form
37 |
38 | **Documentation and infrastructure:**
39 |
40 | - add basic cabal test suites for hledger-lib and hledger
41 |
42 |
43 | Release contributors:
44 |
45 | - Xinruo Sun enhanced the hledger-web add form
46 | - Clint Adams added cabal test suites
47 | - Jeff Richards did hledger-web cleanup
48 | - Peter Simons provided the build bot
49 |
--------------------------------------------------------------------------------
/hledger-web/templates/homepage.hamlet:
--------------------------------------------------------------------------------
1 | _{MsgHello}
2 |
3 |
4 | - Now that you have a working project you should use the #
5 | \Yesod book to learn more. #
6 | You can also use this scaffolded site to explore some basic concepts.
7 |
8 |
- This page was generated by the #{handlerName} handler in #
9 | \Handler/Home.hs.
10 |
11 |
- The #{handlerName} handler is set to generate your site's home screen in Routes file #
12 | config/routes
13 |
14 |
- The HTML you are seeing now is actually composed by a number of widgets, #
15 | most of them are brought together by the defaultLayout function which #
16 | is defined in the Foundation.hs module, and used by #{handlerName}. #
17 | All the files for templates and wigdets are in templates.
18 |
19 |
-
20 | A Widget's Html, Css and Javascript are separated in three files with the #
21 | \.hamlet, .lucius and .julius extensions.
22 |
23 |
- If you had javascript enabled then you wouldn't be seeing this.
24 |
25 |
-
26 | This is an example trivial Form. Read the #
27 | \Forms chapter #
28 | on the yesod book to learn more about them.
29 | $maybe (info,con) <- submission
30 |
31 | Your file's type was
#{fileContentType info}. You say it has:
#{con}
32 |