UMM 0.1.0 → 0.1.1
raw patch · 8 files changed
+103/−40 lines, 8 filesdep +utf8-string
Dependencies added: utf8-string
Files
- README +13/−3
- UMM.cabal +2/−2
- UMM.hs +3/−3
- UMMData.hs +6/−10
- UMMEval.hs +9/−9
- UMMHelp.hs +9/−7
- UMMParser.hs +58/−5
- sample1.dat +3/−1
README view
@@ -1,3 +1,5 @@+$Id: README,v 1.3 2009/11/21 06:05:50 uwe Exp $+ Umm is an extremely minimal command-line program to read a plain-text ledger file and report balance and other information. Although minimal, it aims to be able to handle multiple accounts, currencies,@@ -6,9 +8,9 @@ Umm should have no dependencies other than a haskell compiler and standard libraries, although I've not tested it with anything except-ghc. I've built it with both ghc 6.8.3 on an iMac G3 running OSX-10.3.9 and ghc 6.10.3 on an x86 running Ubuntu. You should be able to-build umm simply by running+ghc. I've built it with ghc 6.8.3 on an iMac G3 running OSX 10.3.9,+ghc 6.10.3 on an x86 running Ubuntu, and ghc 6.10.x(1?) on an x86+running Windows XP. You should be able to build umm simply by running cabal configure && cabal build @@ -16,3 +18,11 @@ output of that. Arguably, that info should be in this file... later. Then look at the two files sample1.dat and sample2.dat; they are very simple examples of ledgers.++If you want to use Unicode currency symbols... umm can't do that yet.+However, please have a look at the shell script ummw in this+distribution. You'll have to do a tiny bit of editing to customize+that shell script, but you should be able to make it turn your+favorite currency symbol(s) into stuff that umm can understand,+then reverse that transformation on the output of umm. Then just+use ummw as a wrapper around umm, and you should be all set!
UMM.cabal view
@@ -1,5 +1,5 @@ Name: UMM-Version: 0.1.0+Version: 0.1.1 Homepage: http://www.korgwal.com/umm/ Author: Uwe Hollerbach <uh@alumni.caltech.edu> Maintainer: Uwe Hollerbach <uh@alumni.caltech.edu>@@ -17,7 +17,7 @@ Category: Finance Executable umm- Build-Depends: base >= 4 && < 5, haskell98, parsec, old-time+ Build-Depends: base >= 4 && < 5, haskell98, parsec, old-time, utf8-string Main-is: UMM.hs Other-Modules: UMMData UMMParser
UMM.hs view
@@ -16,17 +16,17 @@ along with umm; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -$Id: UMM.hs,v 1.38 2009/11/18 22:30:35 uwe Exp $ -}+$Id: UMM.hs,v 1.39 2009/11/22 22:09:08 uwe Exp $ -} module Main where-import Prelude+import Prelude hiding (putStr,putStrLn,readFile,getContents) import Control.Monad import Data.List import Data.Maybe import Data.Ratio import System import System.Exit-import System.IO+import System.IO.UTF8 import System.Time import UMMHelp
UMMData.hs view
@@ -16,18 +16,14 @@ along with umm; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -$Id: UMMData.hs,v 1.29 2009/11/18 22:30:36 uwe Exp $ -}+$Id: UMMData.hs,v 1.30 2009/11/22 22:43:06 uwe Exp $ -} -module UMMData (Name(Name), Date(Date), Amount(Amount), start_time,- Command(BalanceCmd, RegisterCmd, ReconcileCmd, ListDataCmd,- ToDoCmd, PriceCmd, ChangeCmd, BasisCmd), CmdOpt(COLAll, COLCCS,- COLAccts, COLGrps, COLIncs, COLExps), Record(CCSRec, IncomeRec,- ExpenseRec, AccountRec, ToDoRec, PriceRec, XferRec, ExchRec,- SplitRec, GroupRec, CommentRec, ErrorRec), genDate,+module UMMData (Name(..), Date(..), Amount(..), start_time,+ Command(..), CmdOpt(..), Record(..), genDate, getRecDate, cmpRecDate, getRecName, cmpRecName,- Ledger(Ledger), runLedger, getResult, getInfo, getErrs,- recordInfo, recordErr, recordNil, BSE(B,S,E),- CCSAmt(CCSAmount), cmpCCSAmountName, eqCCSAmountName,+ Ledger(..), runLedger, getResult, getInfo, getErrs,+ recordInfo, recordErr, recordNil, BSE(..),+ CCSAmt(..), cmpCCSAmountName, eqCCSAmountName, noName, todoName, joinDrop, isLeap, validDate) where import Prelude import Data.Char
UMMEval.hs view
@@ -16,14 +16,14 @@ along with umm; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -$Id: UMMEval.hs,v 1.23 2009/11/18 22:30:36 uwe Exp $ -}+$Id: UMMEval.hs,v 1.24 2009/11/22 22:09:08 uwe Exp $ -} module UMMEval (validateRecs, classifyRecs, validateTransPrices, generateImplicitPrices, getBalances, getPrices) where-import Prelude+import Prelude hiding (putStr,putStrLn) import Data.List import Data.Maybe-import System.IO+import System.IO.UTF8 import Control.Monad import UMMData@@ -36,8 +36,8 @@ do let (_,i,e) = runLedger (chk records) if length e == 0 then return i- else hPutStrLn stderr "There were parse or date errors in the input:"- >> mapM_ (hPutStrLn stderr . show) e+ else putStrLn "There were parse or date errors in the input:"+ >> mapM_ (putStrLn . show) e >> error "quitting now" where chk [] = return () chk (r@(ErrorRec _):rs) = recordErr r >> chk rs@@ -99,8 +99,8 @@ validateTransPrices ccs incs exps accts tps = do let bads = filter chk tps when (length bads > 0)- (hPutStrLn stderr "There were bad transactions in the input:"- >> mapM_ (hPutStrLn stderr . show) bads >> error "quitting now")+ (putStrLn "There were bad transactions in the input:"+ >> mapM_ (putStrLn . show) bads >> error "quitting now") where chk (SplitRec _ c (Amount amt1) (Amount amt2)) = amt1 == 0 || amt2 == 0 || notIn c ccs chk (PriceRec _ _ (CCSAmount c1 amt1) (CCSAmount c2 _)) =@@ -229,8 +229,8 @@ i = dropWhile (\t -> compare (getRecDate (fst t)) date1 == LT) i1 ss = if dorec then showT else showTB when (length e > 0)- (hPutStrLn stderr "There were parse or date errors in the input:"- >> mapM_ (hPutStrLn stderr . show) e >> error "quitting now")+ (putStrLn "There were processing errors in the input:"+ >> mapM_ (putStrLn . show) e >> error "quitting now") when (length i > 0) (putStrLn "Notes:" >> mapM_ ss i >> putStrLn "") return r
UMMHelp.hs view
@@ -16,12 +16,13 @@ along with umm; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -$Id: UMMHelp.hs,v 1.14 2009/11/18 19:58:47 uwe Exp $ -}+$Id: UMMHelp.hs,v 1.16 2009/11/22 22:09:09 uwe Exp $ -} module UMMHelp (writeHdr, usageMsg) where-import Prelude+import Prelude hiding (putStr,putStrLn)+import System.IO.UTF8 -version = "0.1.0"+version = "0.1.1" writeHdr = putStrLn@@ -118,7 +119,7 @@ " 'ccs' name [desc]\n" ++ " 'income' name [desc]\n" ++ " 'expense' name [desc]\n" ++- " 'account' name date [desc]\n" +++ " 'account' name [date] [desc]\n" ++ " 'group' name [name...]\n" ++ " 'price' date [amount1] name1 amount2 [name2]\n" ++ " 'split' date name amount1 amount2\n" ++@@ -162,7 +163,7 @@ " for documentation, it's not used by the program.\n" ++ "\n" ++ "\n" ++- "* 'account name date [desc]' records specify accounts where you\n" +++ "* 'account name [date] [desc]' records specify accounts where you\n" ++ " want to keep of the quantity of what's in the account as well\n" ++ " as transactions which move stuff into or out of the account.\n" ++ " An account can contain multiple types of ccs, for example a\n" ++@@ -308,8 +309,9 @@ "In the above:\n" ++ "\n" ++ "* 'name' is a sequence of non-blank characters whose first\n" ++- " character is a letter and whose remaining characters are\n" ++- " letters or digits or symbols from the set !$%&*+-/:<=>?@^_~\n" +++ " character is a letter or a currency symbol and whose remaining\n" +++ " characters are letters or currency symbols or digits or symbols\n" +++ " from the set !%&*+-/:<=>?@^_~\n" ++ "\n" ++ "\n" ++ "* 'date' is a date formatted as Y/M/D or Y-M-D, where no\n" ++
UMMParser.hs view
@@ -16,7 +16,7 @@ along with umm; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -$Id: UMMParser.hs,v 1.28 2009/11/14 22:41:36 uwe Exp $ -}+$Id: UMMParser.hs,v 1.29 2009/11/22 22:09:09 uwe Exp $ -} -- TODO: template := <to be determined> @@ -72,12 +72,65 @@ -- TODO: are there some here that we need to add or remove? -symbol = oneOf "!$%&*+-/:<=>?@^_~"+-- Currency symbols: do allow these as the first char of a name+-- gathered from various places on the web, mainly unicode.org +currency_symbol = oneOf $+ map chr [0x24, -- dollar+ 0xa2, -- cent+ 0xa3, -- pound+ 0xa4, -- generic currency symbol+ 0xa5, -- yen+ 0x192, -- florin+ 0x9f2, -- Bengali rupee 1+ 0x9f3, -- Bengali rupee 2+ 0xaf1, -- gujarati rupee+ 0xbf9, -- Tamil rupee+ 0xe2f, -- Thai baht+ 0x17db, -- Khmer currency symbol+ 0x20a0, -- euro-currency (not euro)+ 0x20a1, -- colon+ 0x20a2, -- Brazilian cruzeiro+ 0x20a3, -- French franc+ 0x20a4, -- Italian lira+ 0x20a5, -- mill+ 0x20a6, -- Nigerian naira+ 0x20a7, -- Spanish peseta+ 0x20a8, -- Indian rupee+ 0x20a9, -- Korean won+ 0x20aa, -- Israeli new sheqel+ 0x20ab, -- Vietnamese dong+ 0x20ac, -- European euro+ 0x20ad, -- Laotian kip+ 0x20ae, -- Mongolian tugrik+ 0x20af, -- Greek drachma+ 0x20b0, -- German pfennig+ 0x20b1, -- Phillipine peso+ 0x20b2, -- Paraguayan guarani ???+ 0x20b3, -- austral ???+ 0x20b4, -- Ukrainian hryvnia ???+ 0x20b5, -- Ghanaian cedi ???+ 0x20b6, -- livre tournois ???+ 0x20b7, -- spesmilo ???+ 0x20b8, -- tenge ???+ 0x3350, -- yuan 1+ 0x5143, -- Chinese yuan+ 0x5186, -- yen 2+ 0x5706, -- yen/yuan variant+ 0x570e, -- yen/yuan variant+ 0x5713, -- yuan variant+ 0x571c, -- yuan variant+ 0xa838, -- North Indic rupee ???+ 0xfdfc] -- Iranian rial++-- Non-currency symbols: don't allow these as the first character of a name++other_symbol = oneOf "!%&*+-/:<=>?@^_~"+ parseName = do spaces- first <- letter- rest <- many (letter <|> digit <|> symbol)+ first <- letter <|> currency_symbol+ rest <- many (letter <|> currency_symbol <|> digit <|> other_symbol) return (Name (first:rest)) parseOptionalName = option (Name "") (TPCP.try parseName)@@ -155,7 +208,7 @@ parseAccount = do string "account" name <- parseName- date <- parseDate+ date <- option start_time (TPCP.try parseDate) desc <- parseOptionalString return (AccountRec name date desc)
sample1.dat view
@@ -1,4 +1,6 @@-ccs US$ "The Almighty Buck"+ccs € "The Almighty Euro"+ccs $ "The Almighty Buck"+ccs ¥ "The Almighty Yen" income cash income interest expense cash