penny-lib-0.6.0.0: Extensible double-entry accounting system - library

Safe HaskellNone

Penny.Copper.Render

Contents

Description

Renders Penny data in a format that can be parsed by Penny.Copper.Parsec. These functions render text that is compliant with the EBNF grammar which is at doc/ledger-grammar.org.

Synopsis

Helpers

txtWords :: [Text] -> TextSource

Merges a list of words into one Text; however, if any given Text is empty, that Text is first dropped from the list.

renMaybe :: Maybe a -> (a -> Maybe Text) -> Maybe TextSource

Takes a field that may or may not be present and a function that renders it. If the field is not present at all, returns an empty Text. Otherwise will succeed or fail depending upon whether the rendering function succeeds or fails.

Accounts

isSubAcctLvl1 :: SubAccount -> BoolSource

Is True if a sub account can be rendered at Level 1; False otherwise.

ledgerAcct :: Account -> Maybe TextSource

Shows an account, with the minimum level of quoting possible. Fails with an error if any one of the characters in the account name does not satisfy the lvl1Char predicate. Otherwise returns a rendered account, quoted if necessary.

Commodities

quotedLvl1Cmdty :: Commodity -> Maybe TextSource

Render a quoted Level 1 commodity. Fails if any character does not satisfy lvl1Char.

lvl2Cmdty :: Commodity -> Maybe TextSource

Render a Level 2 commodity. Fails if the first character is not a letter or a symbol, or if any other character is a space.

lvl3Cmdty :: Commodity -> Maybe TextSource

Render a Level 3 commodity. Fails if any character is not a letter or a symbol.

Quantities

data GroupSpec Source

Specifies how to perform digit grouping when rendering a quantity. All grouping groups into groups of 3 digits.

Constructors

NoGrouping

Do not perform any digit grouping

GroupLarge

Group digits, but only if the number to be grouped is greater than 9,999 (if grouping the whole part) or if there are more than 4 decimal places (if grouping the fractional part).

GroupAll

Group digits whenever there are at least four decimal places.

data GroupSpecs Source

Constructors

GroupSpecs 

Fields

left :: GroupSpec
 
right :: GroupSpec
 

Instances

groupWhole :: GroupSpec -> String -> StringSource

Performs grouping for amounts to the left of the radix point.

groupDecimal :: GroupSpec -> String -> StringSource

Performs grouping for amounts to the right of the radix point.

quantitySource

Arguments

:: GroupSpecs

Group for the portion to the left and right of the radix point?

-> Qty 
-> Text 

Renders an unquoted Qty. Performs digit grouping as requested.

Amounts

amount :: GroupSpecs -> Amount -> Maybe TextSource

Render an Amount. The Format is required so that the commodity can be displayed in the right place.

Comments

DateTime

dateTime :: DateTime -> TextSource

Render a DateTime. The day is always printed. If the time zone offset is not zero, then the time and time zone offset are both printed. If the time zone offset is zero, then the hours and minutes are printed, but only if the time is not midnight. If the seconds are not zero, they are also printed.

showX :: Show a => a -> TextSource

Entries

Flags

Memos

postingMemoLineSource

Arguments

:: Int

Pad the end of the output with this many spaces

-> Text 
-> Maybe Text 

Renders a postingMemoLine, optionally with trailing whitespace. The trailing whitespace allows the next line to be indented properly if is also a postingMemoLine. This is handled using trailing whitespace rather than leading whitespace because leading whitespace is inconsistent with the grammar.

postingMemo :: Bool -> Memo -> Maybe TextSource

Renders a postingMemo. Fails if the postingMemo is empty, as the grammar requires that they have at least one line.

If the boolean is True, inserts padding after the last postingMemoLine so that the next line is indented by four columns. Use this if the posting memo is followed by another posting. If the last boolean if False, there is no indenting after the last postingMemoLine.

Numbers

Payees

Prices

Tags

TopLine

topLine :: TopLine -> Maybe TextSource

Renders the TopLine. Emits trailing whitespace after the newline so that the first posting is properly indented.

Posting

postingSource

Arguments

:: GroupSpecs 
-> Bool

If True, emit four spaces after the trailing newline.

-> Posting 
-> Maybe Text 

Renders a Posting. Fails if any of the components fail to render. In addition, if the unverified Posting has an Entry, a Format must be provided, otherwise render fails.

The columns look like this. Column numbers begin with 0 (like they do in Emacs) rather than with column 1 (like they do in Vim). (Really Emacs is the strange one; most CLI utilities seem to start with column 1 too...)

 ID COLUMN WIDTH WHAT
 ---------------------------------------------------
 A    0      4     Blank spaces for indentation
 B    4      50    Flag, Number, Payee, Account, Tags
 C    54     2     Blank spaces for padding
 D    56     NA    Entry

Omit the padding after column B if there is no entry; also omit columns C and D entirely if there is no Entry. (It is annoying to have extraneous blank space in a file).

This table is a bit of a lie, because the blank spaces for indentation are emitted either by the posting previous to this one (either after the posting itself or after its postingMemo) or by the TopLine.

Also emits an additional eight spaces after the trailing newline if the posting has a memo. That way the memo will be indented properly. (There are trailing spaces here, as opposed to leading spaces in the posting memo, because the latter would be inconsistent with the grammar.)

Emits an extra four spaces after the first line if the first paramter is True. However, this is overriden if there is a memo, in which case eight spaces will be emitted. (This allows the next posting to be indented properly.)

formatterSource

Arguments

:: Bool

If True, emit four trailing spaces if no memo or eight trailing spaces if there is a memo.

-> Text

Flag

-> Text

Number

-> Text

Payee

-> Text

Account

-> Text

Tags

-> Text

Entry

-> Text

Memo

-> Text 

Transaction

Item

Ledger