* TO DO ** make balance fast *** TODO profile again *** TODO add CookedLedger caching txns etc. ** basic features *** print *** !include *** , in thousands *** -j and -J graph data output ** advanced features *** handle mixed amounts *** 3.0-style elision *** -p period expressions *** -d display expressions *** read gnucash files *** other args, directives ** new features *** feature: read timelog files **** fix up Amounts ***** allow flexible display by currency ***** allow parsing by currency ***** fix arithmetic **** timelog parser handle time amounts switch to Data.Time.* fix errors - read seconds to pico try System.Time ? *** timelog simple format *** auto-generate missing clock-out *** graph automation *** entry and smart data entry *** incorporate timeclock features *** better layout ** testing *** better use of quickcheck/smallcheck http://blog.codersbase.com/2006/09/01/simple-unit-testing-in-haskell/ *** ledger compatibility tests ** documentation *** literate docs *** better use of haddock ** marketing *** set up as a cabal/hackage project following wiki howto ? http://en.wikibooks.org/wiki/Haskell/Packaging *** announce on haskell list, wiki * things I want to know ** time where have I been spending my time in recent weeks ? where have I spent my time today ? what is my status wrt spending plan for this week/month/year ? what is my current status wrt time spending goals ? ** money where have I been spending my money ? what is my status wrt spending plan for this week/month/year ? what is my current status wrt spending/savings goals ? what are all my current balances ? what does my balance history look like ? what does my balance future look like ? are there any cashflow, tax, budgetary problems looming ? * misc ** testing support -- {- | looks in Tests.hs for functions like prop_foo and returns -- the list. Requires that Tests.hs be valid Haskell98. -} -- tests :: [String] -- tests = unsafePerformIO $ -- do h <- openFile "src/Tests.hs" ReadMode -- s <- hGetContents h -- case parseModule s of -- (ParseOk (HsModule _ _ _ _ ds)) -> return (map declName (filter isProp ds)) -- (ParseFailed loc s’) -> error (s’ ++ ” ” ++ show loc) -- {- | checks if function binding name starts with @prop_@ indicating -- that it is a quickcheck property -} -- isProp :: HsDecl -> Bool -- isProp d@(HsFunBind _) = “prop_” `isPrefixOf` (declName d) -- isProp _ = False -- {- | takes an HsDecl and returns the name of the declaration -} -- declName :: HsDecl -> String -- declName (HsFunBind (HsMatch _ (HsIdent name) _ _ _:_)) = name -- declName _ = undefined -- mkCheck name = [| putStr (name ++ ": ") -- >> quickCheck $(varE (mkName name)) |] -- mkChecks [] = undefined -- if we don't have any tests, then the test suite is undefined right? -- mkChecks [name] = mkCheck name -- mkChecks (name:ns) = [| $(mkCheck name) >> $(mkChecks ns) |] -- {-# OPTIONS_GHC -fno-warn-unused-imports -no-recomp -fth #-} -- runTests :: IO () -- runTests = $(mkChecks tests) -- ghc --make Unit.hs -main-is Unit.runTests -o unit