summaryrefslogtreecommitdiff
path: root/bin/penny-main.hs
blob: c0d5bd914c326b80757d578bf64203e1e9598f87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
module Main where

import Penny
import qualified Paths_penny as PPB

-- | This type contains settings for all the reports, as well as
-- default settings for the global options. Some of these can be
-- overridden on the command line.
defaults :: Runtime -> Defaults
defaults rt = Defaults
  { caseSensitive = False
    -- ^ Whether the matcher is case sensitive by default

  , matcher = Within
    -- ^ Which matcher to use. Your choices:
    -- Within
    -- Exact
    -- TDFA (regular expressions, POSIX semantics)
    -- PCRE (regular expressions, PCRE semantics)

  , colorToFile = False
    -- ^ Use colors when standard output is not a terminal?

  , expressionType = Infix
    -- ^ Use Infix or RPN expressions for the posting filters and for
    -- the filters in the Postings report? Change to @RPN@ if you like
    -- that kind of thing (I find RPN easier to enter; if you're not
    -- familiar with it, you might become a convert.)

  , defaultScheme = Just schemeDark
    -- ^ Default color scheme. If Nothing, there is no default color
    -- scheme. If there is no default color scheme and the user does
    -- not pick one on the command line, no colors will be used.

  , additionalSchemes = [schemeDark, schemeLight, schemePlain]
    -- ^ Additional color schemes the user can pick from on the
    -- command line.

  , sorter = [(Date, Ascending)]
    -- ^ Postings are sorted in this order by default. For example, if
    -- the first pair is (Date, Ascending), then postings are first
    -- sorted by date in ascending order. If the second pair is
    -- (Payee, Ascending), then postings with the same date are then
    -- sorted by payee.
    --
    -- If this list is empty, then by default postings are left in the
    -- same order as they appear in the ledger files.

  , formatQty = qtyFormatter $ S3a Period
    -- ^ How to format quantities. This affects only quantities that
    -- are not parsed from the ledger.  Examples include calculated
    -- totals and inferred quantities.  Affects all reports.

  , balanceShowZeroBalances = False
    -- ^ Show zero balances in the balance report? If True, show them;
    -- if False, hide them.

  , balanceOrder = Ascending
    -- ^ Whether to sort the accounts in ascending or descending order
    -- by account name in the balance report. Your choices: Ascending
    -- or Descending.

  , convertShowZeroBalances = False
    -- ^ Show zero balances in the convert report? If True, show them;
    -- if False, hide them.

  , convertTarget = AutoTarget
    -- ^ The commodity to which to convert the commodities in the
    -- convert report. Your choices:
    --
    -- AutoTarget - selects a target commodity automatically, based on
    -- which commodity is the most common target commodity in the
    -- prices in your ledger files. If there is a tie for most common
    -- target commodity, the target that appears later in your ledger
    -- files is used.
    --
    -- ManualTarget CMDTY_NAME - always use the given commodity.

  , convertOrder = Ascending
    -- ^ Sort the convert report in ascending or descending order.

  , convertSortBy = SortByName
    -- ^ Sort by account or by quantity in the convert report. Your
    -- choices:
    --
    -- SortByQty
    -- SortByName

  , postingsFields = fields
    -- ^ Fields to show by default in the postings report.

  , postingsWidth = widthFromRuntime rt
    -- ^ The postings report is roughly this wide by default. Use
    -- @widthFromRuntime rt@ if you want to use the current width of
    -- your terminal.

  , postingsShowZeroBalances = False
    -- ^ Show zero balances in the postings report? If True, show
    -- them; if False, hide them.

  , postingsDateFormat = yearMonthDay
    -- ^ How to format dates in the postings report.

  , postingsSubAccountLength = 2
    -- ^ Account names in the postings report are shortened if
    -- necessary in order to help the report fit within the allotted
    -- width (see postingsWidth). Account names are only shortened as
    -- much as is necessary for them to fit; however, each sub-account
    -- name will not be shortened any more than the amount given here.
    --
    -- This number should be a non-negative integer.

  , postingsPayeeAllocation = 40
    -- ^ postingsPayeeAllocation and postingsAccountAllocation
    -- determine how much space is allotted to the payee and account
    -- fields in the postings report. These fields are variable
    -- width. After space for most other fields is allotted, space is
    -- allotted for these two fields. The two fields divide the space
    -- proportionally depending on postingsPayeeAllocation and
    -- postingsAccountAllocation. For example, if
    -- postingsPayeeAllocation is 60 and postingsAccountAllocation is
    -- 40, then the payee field gets 60 percent of the leftover space
    -- and the account field gets 40 percent of the leftover space.
    --
    -- Both postingsPayeeAllocation and postingsAccountAllocation
    -- must be positive integers; if either one is less than 1, your
    -- program will crash at runtime.

  , postingsAccountAllocation = 60
    -- ^ See postingsPayeeAllocation above for an explanation

  , postingsSpacers = spacers
    -- ^ Determines the number of spaces that appears to the right of
    -- each named field; for example, sPayee indicates how many spaces
    -- will appear to the right of the payee field. Each field of the
    -- Spacers should be a non-negative integer (although currently
    -- the absolute value of the field is taken.)
  }

-- | Controls which fields appear in the report by default.
fields :: Fields Bool
fields = Fields
  { fGlobalTransaction = False
  , fRevGlobalTransaction = False
  , fGlobalPosting = False
  , fRevGlobalPosting = False
  , fFileTransaction = False
  , fRevFileTransaction = False
  , fFilePosting = False
  , fRevFilePosting = False
  , fFiltered = False
  , fRevFiltered = False
  , fSorted = False
  , fRevSorted = False
  , fVisible = False
  , fRevVisible = False
  , fLineNum = False
  , fDate = True
  , fFlag = False
  , fNumber = False
  , fPayee = True
  , fAccount = True
  , fPostingDrCr = True
  , fPostingCmdty = True
  , fPostingQty = True
  , fTotalDrCr = True
  , fTotalCmdty = True
  , fTotalQty = True
  , fTags = False
  , fMemo = False
  , fFilename = False
  }

-- | Controls how many spaces appear to the right of each named field.
spacers :: Spacers Int
spacers = Spacers
  { sGlobalTransaction = 1
  , sRevGlobalTransaction = 1
  , sGlobalPosting = 1
  , sRevGlobalPosting = 1
  , sFileTransaction = 1
  , sRevFileTransaction = 1
  , sFilePosting = 1
  , sRevFilePosting = 1
  , sFiltered = 1
  , sRevFiltered = 1
  , sSorted = 1
  , sRevSorted = 1
  , sVisible = 1
  , sRevVisible = 1
  , sLineNum = 1
  , sDate = 1
  , sFlag = 1
  , sNumber = 1
  , sPayee = 4
  , sAccount = 1
  , sPostingDrCr = 1
  , sPostingCmdty = 1
  , sPostingQty = 1
  , sTotalDrCr = 1
  , sTotalCmdty = 1
  }

-- | The light color scheme. You can change various values below to
-- affect the color scheme.
schemeLight :: Scheme
schemeLight = Scheme "light" "for light background terminals"
              lightLabels

lightLabels :: Labels (EvenAndOdd (Chunk -> Chunk))
lightLabels = Labels
  { debit = EvenAndOdd { eoEven = lightDebit lightEvenTextSpec
                       , eoOdd = lightDebit lightOddTextSpec }
  , credit = EvenAndOdd { eoEven = lightCredit lightEvenTextSpec
                        , eoOdd = lightCredit lightOddTextSpec }
  , zero = EvenAndOdd { eoEven = lightZero lightEvenTextSpec
                      , eoOdd = lightZero lightOddTextSpec }
  , other = EvenAndOdd { eoEven = lightEvenTextSpec
                       , eoOdd = lightOddTextSpec }
  }

lightEvenTextSpec :: Chunk -> Chunk
lightEvenTextSpec = id

lightOddTextSpec :: Chunk -> Chunk
lightOddTextSpec = (<> (c8_b_default <> c256_b_255))

lightDebit :: (Chunk -> Chunk) -> Chunk -> Chunk
lightDebit f c = f c <> c8_f_magenta <> c256_f_52

lightCredit :: (Chunk -> Chunk) -> Chunk -> Chunk
lightCredit f c = f c <> c8_f_cyan <> c256_f_21

lightZero :: (Chunk -> Chunk) -> Chunk -> Chunk
lightZero f c = f c <> c8_f_black <> c256_f_0

-- | The dark color scheme. You can change various values below to
-- affect the color scheme.
schemeDark :: Scheme
schemeDark = Scheme "dark" "for dark background terminals"
              darkLabels

darkLabels :: Labels (EvenAndOdd (Chunk -> Chunk))
darkLabels = Labels
  { debit = EvenAndOdd { eoEven = darkDebit darkEvenTextSpec
                       , eoOdd = darkDebit darkOddTextSpec }
  , credit = EvenAndOdd { eoEven = darkCredit darkEvenTextSpec
                        , eoOdd = darkCredit darkOddTextSpec }
  , zero = EvenAndOdd { eoEven = darkZero darkEvenTextSpec
                      , eoOdd = darkZero darkOddTextSpec }
  , other = EvenAndOdd { eoEven = darkEvenTextSpec
                       , eoOdd = darkOddTextSpec }
  }

darkEvenTextSpec :: Chunk -> Chunk
darkEvenTextSpec = id

darkOddTextSpec :: Chunk -> Chunk
darkOddTextSpec = (<> (c8_b_default <> c256_b_235))

darkDebit :: (Chunk -> Chunk) -> Chunk -> Chunk
darkDebit f c = f c <> c8_f_magenta <> c256_f_208

darkCredit :: (Chunk -> Chunk) -> Chunk -> Chunk
darkCredit f c = f c <> c8_f_cyan <> c256_f_45

darkZero :: (Chunk -> Chunk) -> Chunk -> Chunk
darkZero f c = f c <> c8_f_white <> c256_f_15


-- | Plain scheme has no colors at all.
schemePlain :: Scheme
schemePlain = Scheme "plain" "uses default terminal colors"
              plainLabels

plainLabels :: Labels (EvenAndOdd (Chunk -> Chunk))
plainLabels = Labels
  { debit = EvenAndOdd id id
  , credit = EvenAndOdd id id
  , zero = EvenAndOdd id id
  , other = EvenAndOdd id id
  }

main :: IO ()
main = runPenny PPB.version defaults