]> Git — Sourcephile - comptalang.git/blob - cli/Hcompta/CLI/Lang.hs
Refactor hcompta-lib.
[comptalang.git] / cli / Hcompta / CLI / Lang.hs
1 {-# LANGUAGE FlexibleContexts #-}
2 {-# LANGUAGE FlexibleInstances #-}
3 {-# LANGUAGE MultiParamTypeClasses #-}
4 {-# LANGUAGE OverloadedStrings #-}
5 {-# LANGUAGE TupleSections #-}
6 {-# OPTIONS_GHC -fno-warn-orphans #-}
7 module Hcompta.CLI.Lang where
8
9 import qualified Data.List as List
10 import Data.Maybe (catMaybes, fromMaybe)
11 import qualified Data.Text as Text
12 import Data.Text (Text)
13 import qualified Data.Text.Lazy as TL
14 import Data.Monoid ((<>))
15 import Prelude hiding (error)
16 import qualified System.Environment as Env
17 import qualified System.IO.Memoize as IO
18 import qualified Text.Parsec as Parsec
19 import qualified Text.Parsec.Error as Parsec.Error
20 import qualified Text.Parsec.Error.Custom as Parsec
21
22 import qualified Hcompta as H
23 import qualified Hcompta.Ledger as Ledger
24 import qualified Hcompta.JCC as JCC
25
26 import Text.WalderLeijen.ANSI.Text (ToDoc(..))
27 import qualified Text.WalderLeijen.ANSI.Text as W
28
29 -- * Type 'Lang'
30 data Lang
31 = EN
32 | FR
33 deriving (Show)
34
35 -- * Class 'Translate'
36 class Translate from to where
37 translate :: Lang -> from -> to
38 instance Translate e e where
39 translate _lang = id
40
41 -- TODO: check that this is expected behavior
42 -- and portability issues.
43 from_Env :: IO Lang
44 from_Env = do
45 io_env <- IO.once Env.getEnvironment
46 (<$> io_env) $ \env ->
47 fromMaybe EN $ from_Strings $
48 List.concatMap
49 ((\lang ->
50 let short = takeWhile (/= '_') lang in
51 if short == lang
52 then [lang]
53 else [lang, short])
54 . List.takeWhile (/= '.') ) $
55 catMaybes
56 [ List.lookup "LC_ALL" env
57 , List.lookup "LC_CTYPE" env
58 , List.lookup "LANG" env
59 ]
60
61 from_Strings :: [String] -> Maybe Lang
62 from_Strings s =
63 case s of
64 ("fr" :_) -> Just FR
65 ("fr_FR":_) -> Just FR
66 ("en" :_) -> Just EN
67 ("en_US":_) -> Just EN
68 (_:xs) -> from_Strings xs
69 [] -> Nothing
70
71 (#) :: ToDoc () a => a -> W.Doc
72 (#) = toDoc ()
73
74 instance ToDoc () Text where
75 toDoc _ = W.strict_text
76 instance ToDoc () String where
77 toDoc _ = W.strict_text . Text.pack
78 instance ToDoc () Int where
79 toDoc _ = W.int
80 instance ToDoc () Integer where
81 toDoc _ = W.integer
82 instance ToDoc () JCC.Unit where
83 toDoc _ = JCC.write_unit
84 instance ToDoc () H.Account_Anchor where
85 toDoc _ = JCC.write_account_anchor
86 instance ToDoc () H.Transaction_Anchor where
87 toDoc _ = JCC.write_transaction_anchor
88 instance ToDoc () (JCC.Amount_Styled JCC.Amount) where
89 toDoc _ = JCC.write_amount
90 instance ToDoc () Ledger.Unit where
91 toDoc _ = Ledger.write_unit
92 instance ToDoc () (Ledger.Amount_Styled Ledger.Amount) where
93 toDoc _ = Ledger.write_amount
94 instance ToDoc () H.Date where
95 toDoc _ = JCC.write_date
96 instance ToDoc Lang JCC.Error_Read_Date where
97 toDoc FR e =
98 case e of
99 JCC.Error_Read_Date_year_or_day_is_missing ->
100 "l’année ou le jour est manquant·e"
101 JCC.Error_Read_Date_invalid_date (year, month, day) ->
102 "date incorrecte (année " <> (#)year <> ", mois " <> (#)month <> ", jour " <> (#)day <> ")"
103 JCC.Error_Read_Date_invalid_time_of_day (hour, minute, second) ->
104 "heure incorrecte (heure " <> (#)hour <> ", minute " <> (#)minute <> ", seconde " <> (#)second <> ")"
105 toDoc EN e =
106 case e of
107 JCC.Error_Read_Date_year_or_day_is_missing ->
108 "year or day is missing"
109 JCC.Error_Read_Date_invalid_date (year, month, day) ->
110 "invalid date (year " <> (#)year <> ", month " <> (#)month <> ", day " <> (#)day <> ")"
111 JCC.Error_Read_Date_invalid_time_of_day (hour, minute, second) ->
112 "invalid time of day (hour " <> (#)hour <> ", minute " <> (#)minute <> ", second " <> (#)second <> ")"
113 instance ToDoc Lang Ledger.Error_Read_Date where
114 toDoc FR e =
115 case e of
116 Ledger.Error_Read_Date_year_or_day_is_missing ->
117 "l’année ou le jour est manquant·e"
118 Ledger.Error_Read_Date_invalid_date (year, month, day) ->
119 "date incorrecte (année " <> (#)year <> ", mois " <> (#)month <> ", jour " <> (#)day <> ")"
120 Ledger.Error_Read_Date_invalid_time_of_day (hour, minute, second) ->
121 "heure incorrecte (heure " <> (#)hour <> ", minute " <> (#)minute <> ", seconde " <> (#)second <> ")"
122 toDoc EN e =
123 case e of
124 Ledger.Error_Read_Date_year_or_day_is_missing ->
125 "year or day is missing"
126 Ledger.Error_Read_Date_invalid_date (year, month, day) ->
127 "invalid date (year " <> (#)year <> ", month " <> (#)month <> ", day " <> (#)day <> ")"
128 Ledger.Error_Read_Date_invalid_time_of_day (hour, minute, second) ->
129 "invalid time of day (hour " <> (#)hour <> ", minute " <> (#)minute <> ", second " <> (#)second <> ")"
130 {-
131 instance Translate Filter.Read.Error W.Doc where
132 translate lang@FR err =
133 case err of
134 Filter.Read.Error_Unknown -> "erreur"
135 Filter.Read.Error_Filter_Date d -> toDoc lang d
136 Filter.Read.Error_Filter_Date_Interval (l, h) ->
137 "mauvais intervalle: (" <> toDoc () l <> ", " <> toDoc () h <> ")"
138 translate lang@EN err =
139 case err of
140 Filter.Read.Error_Unknown -> "error"
141 Filter.Read.Error_Filter_Date d -> toDoc lang d
142 Filter.Read.Error_Filter_Date_Interval (l, h) ->
143 "wrong interval: (" <> toDoc () l <> ", " <> toDoc () h <> ")"
144 -}
145
146 -- * Type 'Account'
147
148 data Account
149 = Account_Equilibrium
150 instance Translate Account Ledger.Account where
151 translate EN t =
152 case t of
153 Account_Equilibrium -> Ledger.account "Equilibrium" []
154 translate FR t =
155 case t of
156 Account_Equilibrium -> Ledger.account "Équilibre" []
157
158 -- * Type 'Comment'
159
160 data Comment
161 = Comment_Equilibrium
162 instance Translate Comment Text where
163 translate EN t =
164 case t of
165 Comment_Equilibrium -> "Equilibrium posting"
166 translate FR t =
167 case t of
168 Comment_Equilibrium -> "Mouvement d’équilibre"
169
170 -- * Type 'Description'
171
172 data Description
173 = Description_Exercise Exercise_OC
174 data Exercise_OC
175 = Exercise_Opening
176 | Exercise_Closing
177 deriving (Eq, Show)
178
179 instance Translate Description Text where
180 translate EN t =
181 case t of
182 Description_Exercise oc ->
183 case oc of
184 Exercise_Opening -> "Opening balance"
185 Exercise_Closing -> "Closing balance"
186 translate FR t =
187 case t of
188 Description_Exercise oc ->
189 case oc of
190 Exercise_Opening -> "Solde d’ouverture"
191 Exercise_Closing -> "Solde de fermeture"
192
193 -- * Type 'Error'
194 data Error
195 = Error_Account_Anchor_is_not_unique Parsec.SourcePos H.Account_Anchor
196 | Error_Account_Anchor_unknown Parsec.SourcePos H.Account_Anchor
197 | Error_Failed_to_include_file FilePath
198 | Error_Failed_to_read_file FilePath
199 | Error_No_input_file_given
200 | Error_One_command_is_required
201 | Error_Option_Balance_Format
202 | Error_Option_Balance_Heritage
203 | Error_Option_Balance_Redundant
204 | Error_Option_Balance_Total
205 | Error_Option_Color
206 | Error_Option_Equilibrium
207 | Error_Option_Equilibrium_Credit
208 | Error_Option_Equilibrium_Debit
209 | Error_Option_Tags_Tree
210 | Error_Option_Verbosity
211 | Error_Transaction_Anchor_unknown Parsec.SourcePos H.Transaction_Anchor
212 | Error_Transaction_Anchor_is_not_unique Parsec.SourcePos H.Transaction_Anchor
213 | Error_Transaction_Invalid_date Integer Int Int
214 | Error_Transaction_Invalid_time_of_day Int Int Integer
215 | Error_Transaction_The_following_transaction_is_not_equilibrated_because
216 | Error_Transaction_The_following_virtual_transaction_is_not_equilibrated_because
217 | Error_Transaction_JCC_Unit_sums_up_to_the_non_null_amount JCC.Unit (JCC.Amount_Styled JCC.Amount)
218 | Error_Transaction_Ledger_Unit_sums_up_to_the_non_null_amount Ledger.Unit (Ledger.Amount_Styled Ledger.Amount)
219 | Error_Transaction_Year_or_day_is_missing
220 | Error_Unkown_command String
221 instance Translate Error W.Doc where
222 translate EN t =
223 case t of
224 Error_Account_Anchor_is_not_unique _pos anchor -> "Account anchor is not unique: " <> (#)anchor
225 Error_Account_Anchor_unknown _pos anchor -> "Account anchor unkown: " <> (#)anchor
226 Error_Failed_to_read_file path -> "failed to read file: " <> (#)path
227 Error_Failed_to_include_file path -> "failed to include file: " <> (#)path
228 Error_No_input_file_given ->
229 W.vsep
230 [ "no input file given, please use:"
231 , "- either -i $hcompta_journal parameter"
232 , "- or HCOMPTA_JOURNAL environment variable."
233 ]
234 Error_One_command_is_required -> "a COMMAND is required"
235 Error_Option_Balance_Format -> "--format option expects \"close\", \"open\", or \"table\" as argument"
236 Error_Option_Balance_Heritage -> "--heritage option expects \"yes\" or \"no\" as argument"
237 Error_Option_Balance_Redundant -> "--redundant option expects \"yes\" or \"no\" as argument"
238 Error_Option_Balance_Total -> "--total option expects \"yes\" or \"no\" as argument"
239 Error_Option_Color -> "--color option expects \"auto\" (default), \"yes\" or \"no\" as argument"
240 Error_Option_Equilibrium -> "--eq option expects an ACCOUNT"
241 Error_Option_Equilibrium_Credit -> "--eq-credit option expects an ACCOUNT"
242 Error_Option_Equilibrium_Debit -> "--eq-debit option expects an ACCOUNT"
243 Error_Option_Tags_Tree -> "--tree option expects \"yes\" or \"no\" as value"
244 Error_Option_Verbosity -> "--verbosity option expects \"error\", \"warn\", \"info\" or \"debug\" as argument"
245 Error_Transaction_Anchor_is_not_unique _pos anchor -> "Transaction anchor is not unique: " <> (#)anchor
246 Error_Transaction_Anchor_unknown _pos anchor -> "Transaction anchor unknown: " <> (#)anchor
247 Error_Transaction_Invalid_date year month dom ->
248 "invalid date (year " <> (#)year <> ", month " <> (#)month <> ", day " <> (#)dom <> ")"
249 Error_Transaction_Invalid_time_of_day hour minute second ->
250 "invalid time of day (hour " <> (#)hour <> ", minute " <> (#)minute <> ", second " <> (#)second <> ")"
251 Error_Transaction_The_following_transaction_is_not_equilibrated_because ->
252 "the following transaction is not equilibrated, because:"
253 Error_Transaction_The_following_virtual_transaction_is_not_equilibrated_because ->
254 "the following virtual transaction is not equilibrated, because:"
255 Error_Transaction_JCC_Unit_sums_up_to_the_non_null_amount unit amount ->
256 " - " <>
257 (if Text.null $ H.unit_text unit
258 then "empty unit"
259 else "unit " <> (#)unit) <>
260 " sums up to the non-null amount: " <> (#)amount
261 Error_Transaction_Ledger_Unit_sums_up_to_the_non_null_amount unit amount ->
262 " - " <>
263 (if Text.null $ H.unit_text unit
264 then "empty unit"
265 else "unit " <> (#)unit) <>
266 " sums up to the non-null amount: " <> (#)amount
267 Error_Transaction_Year_or_day_is_missing ->
268 "year or day is missing"
269 Error_Unkown_command cmd -> "unkown command: " <> (#)cmd
270 translate FR t =
271 case t of
272 Error_Account_Anchor_is_not_unique _pos anchor -> "Ancre de Compte non-unique : " <> (#)anchor
273 Error_Account_Anchor_unknown _pos anchor -> "Ancre de Compte inconnue : " <> (#)anchor
274 Error_Failed_to_read_file path -> "échec de la lecture du fichier : " <> (#)path
275 Error_Failed_to_include_file path -> "échec à l’inclusion du fichier : " <> (#)path
276 Error_No_input_file_given ->
277 W.vsep
278 [ "aucun fichier d’entrée indiqué, veuillez utiliser :"
279 , " - soit le paramètre -i FICHIER_DE_JOURNAL,"
280 , " - soit la variable d’environnement LEDGER_FILE."
281 ]
282 Error_One_command_is_required -> "une COMMANDE est requise"
283 Error_Option_Balance_Format -> "le paramètre --format s’attend à \"close\", \"open\" ou \"table\" comme argument"
284 Error_Option_Balance_Heritage -> "le paramètre --heritage s’attend à \"yes\" ou \"no\" comme argument"
285 Error_Option_Balance_Redundant -> "le paramètre --redundant s’attend à \"yes\" ou \"no\" comme argument"
286 Error_Option_Balance_Total -> "le paramètre --total s’attend à \"yes\" ou \"no\" comme argument"
287 Error_Option_Color -> "le paramètre --color s’attend à \"auto\" (défaut), \"yes\" ou \"no\" comme argument"
288 Error_Option_Equilibrium -> "le paramètre --eq s’attend à un COMPTE"
289 Error_Option_Equilibrium_Credit -> "le paramètre --eq-credit s’attend à un COMPTE"
290 Error_Option_Equilibrium_Debit -> "le paramètre --eq-debit s’attend à un COMPTE"
291 Error_Option_Tags_Tree -> "le paramètre --total s’attend à \"yes\" ou \"no\" comme argument"
292 Error_Option_Verbosity -> "le paramètre --verbosity s’attend à \"error\", \"warn\", \"info\", or \"debug\" comme argument"
293 Error_Transaction_Anchor_is_not_unique _pos anchor -> "Ancre d’Écriture non-unique : " <> (#)anchor
294 Error_Transaction_Anchor_unknown _pos anchor -> "Ancre d’Écriture inconnue : " <> (#)anchor
295 Error_Transaction_Invalid_date year month dom ->
296 "date incorrecte (année " <> (#)year <> ", mois " <> (#)month <> ", jour " <> (#)dom <> ")"
297 Error_Transaction_Invalid_time_of_day hour minute second ->
298 "heure incorrecte (heure " <> (#)hour <> ", minute " <> (#)minute <> ", seconde " <> (#)second <> ")"
299 Error_Transaction_The_following_transaction_is_not_equilibrated_because ->
300 "la transaction suivante n’est pas équilibrée, car :"
301 Error_Transaction_The_following_virtual_transaction_is_not_equilibrated_because ->
302 "la transaction virtuelle suivante n’est pas équilibrée, car :"
303 Error_Transaction_JCC_Unit_sums_up_to_the_non_null_amount unit amount ->
304 " - l’unité " <>
305 (if Text.null $ H.unit_text unit
306 then "vide"
307 else (#)unit) <>
308 " a le solde non-nul : " <> (#)amount
309 Error_Transaction_Ledger_Unit_sums_up_to_the_non_null_amount unit amount ->
310 " - l’unité " <>
311 (if Text.null $ H.unit_text unit
312 then "vide"
313 else (#)unit) <>
314 " a le solde non-nul : " <> (#)amount
315 Error_Transaction_Year_or_day_is_missing ->
316 "l’année ou le jour est manquant-e"
317 Error_Unkown_command cmd -> "commande inconnue : " <> (#)cmd
318
319 -- * Type 'Error_Parsec'
320 data Error_Parsec
321 = Error_Parsec_Expect W.Doc
322 | Error_Parsec_Message String
323 | Error_Parsec_Or
324 | Error_Parsec_Sysunexpect String
325 | Error_Parsec_Sysunexpect_EOI
326 | Error_Parsec_Unexpect W.Doc
327 | Error_Parsec_Unknown
328 instance ToDoc Lang Error_Parsec where
329 toDoc EN t =
330 case t of
331 Error_Parsec_Expect doc -> "but expect : " <> (#)doc
332 Error_Parsec_Message doc -> (#)doc
333 Error_Parsec_Or -> "or"
334 Error_Parsec_Sysunexpect doc -> "is written : " <> (#)doc
335 Error_Parsec_Sysunexpect_EOI -> "end of file unexpected"
336 Error_Parsec_Unexpect doc -> "found : " <> (#)doc
337 Error_Parsec_Unknown -> "unkown"
338 toDoc FR t =
339 case t of
340 Error_Parsec_Expect doc -> "mais s’attend à : " <> (#)doc
341 Error_Parsec_Message doc -> (#)doc
342 Error_Parsec_Or -> "ou"
343 Error_Parsec_Sysunexpect doc -> "est écrit : " <> (#)doc
344 Error_Parsec_Sysunexpect_EOI -> "fin de fichier inattendue"
345 Error_Parsec_Unexpect doc -> "trouve : " <> (#)doc
346 Error_Parsec_Unknown -> "inconnu"
347 instance Translate Parsec.SourcePos W.Doc where
348 translate EN pos = do
349 let line = Parsec.sourceLine pos
350 let col = Parsec.sourceColumn pos
351 case Parsec.sourceName pos of
352 "" -> "(line " <> (#)line <> ", column " <> (#)col <> ")"
353 path -> "(line " <> (#)line <> ", column " <> (#)col <> ") in: " <> (#)path
354 translate FR pos = do
355 let line = Parsec.sourceLine pos
356 let col = Parsec.sourceColumn pos
357 case Parsec.sourceName pos of
358 "" -> "(ligne " <> (#)line <> ", colonne " <> (#)col <> ")"
359 path -> "(ligne " <> (#)line <> ", colonne " <> (#)col <> ") dans : " <> (#)path
360 instance Translate e W.Doc
361 => Translate [Parsec.Error e] W.Doc where
362 translate lang errors =
363 W.vsep $
364 (<$> errors) $ \error ->
365 case error of
366 Parsec.Error_At pos errs -> W.vsep $
367 [ translate lang pos
368 , translate lang errs
369 ]
370 Parsec.Error_Parser err ->
371 W.vsep $
372 [ translate lang (Parsec.errorPos err)
373 , showErrorMessages
374 (Parsec.Error.errorMessages err)
375 ]
376 Parsec.Error_Custom pos err -> W.vsep $
377 [ translate lang pos
378 , translate lang err
379 ]
380 where
381 showErrorMessages :: [Parsec.Error.Message] -> W.Doc
382 showErrorMessages msgs
383 | null msgs = toDoc lang $ Error_Parsec_Unknown
384 | otherwise = W.vsep $ -- clean $
385 [showSysUnExpect, showUnExpect, showExpect, showMessages]
386 where
387 (sysUnExpect,msgs1) = span ((Parsec.Error.SysUnExpect "") ==) msgs
388 (unExpect,msgs2) = span ((Parsec.Error.UnExpect "") ==) msgs1
389 (expect,messages) = span ((Parsec.Error.Expect "") ==) msgs2
390
391 showExpect = showMany (Just (toDoc lang . Error_Parsec_Expect)) expect
392 showUnExpect = showMany (Just (toDoc lang . Error_Parsec_Unexpect)) unExpect
393 showSysUnExpect
394 | not (null unExpect) || null sysUnExpect = W.empty
395 | null firstMsg = toDoc lang $ Error_Parsec_Sysunexpect_EOI
396 | otherwise = toDoc lang $ Error_Parsec_Sysunexpect firstMsg
397 where
398 firstMsg = Parsec.Error.messageString (head sysUnExpect)
399
400 showMessages = showMany Nothing messages
401
402 -- helpers
403 showMany :: (Maybe (W.Doc -> W.Doc)) -> [Parsec.Error.Message] -> W.Doc
404 showMany pre msgs_ =
405 case clean (map Parsec.Error.messageString msgs_) of
406 [] -> W.empty
407 ms ->
408 case pre of
409 Nothing -> commasOr ms
410 Just p -> p $ commasOr ms
411
412 commasOr :: [String] -> W.Doc
413 commasOr [] = W.empty
414 commasOr [m] = W.bold $ W.dullblack $ W.text $ TL.pack m
415 commasOr ms = commaSep (init ms)
416 <> (W.space <> toDoc lang Error_Parsec_Or <> W.space)
417 <> W.bold (W.dullblack $ W.text $ TL.pack $ last ms)
418 commaSep = W.intercalate (W.comma <> W.space)
419 (W.bold . W.dullblack . W.text . TL.pack)
420 . clean
421
422 clean = List.nub . filter (not . null)
423
424 -- * Type 'Header'
425 data Header
426 = Header_Accounts
427 | Header_Accounts_Depth
428 | Header_Journals
429 | Header_Tags
430 | Header_Tags_Distinct
431 | Header_Transactions
432 | Header_Transactions_Date
433 | Header_Units
434 instance Translate Header [Text] where
435 translate EN t =
436 case t of
437 Header_Accounts -> ["Accounts"]
438 Header_Accounts_Depth -> ["Accounts","Depth"]
439 Header_Journals -> ["Journals"]
440 Header_Tags -> ["Tags"]
441 Header_Tags_Distinct -> ["Tags", "Distinct"]
442 Header_Transactions -> ["Transactions"]
443 Header_Transactions_Date -> ["Transactions", "Date"]
444 Header_Units -> ["Unit"]
445 translate FR t =
446 case t of
447 Header_Accounts -> ["Comptes"]
448 Header_Accounts_Depth -> ["Comptes","Profondeur"]
449 Header_Journals -> ["Journaux"]
450 Header_Tags -> ["Tags"]
451 Header_Tags_Distinct -> ["Tags", "Distincts"]
452 Header_Transactions -> ["Écritures"]
453 Header_Transactions_Date -> ["Écritures", "Date"]
454 Header_Units -> ["Unités"]
455
456 -- * Type 'Help'
457 data Help
458 = Help_Command_Balance
459 | Help_Command_General_Ledger
460 | Help_Command_Journal
461 | Help_Command_Journals
462 | Help_Command_Stats
463 | Help_Command_Tags
464 | Help_Option_Balance_Format
465 | Help_Option_Balance_Heritage
466 | Help_Option_Balance_Redundant
467 | Help_Option_Balance_Total
468 | Help_Option_Color
469 | Help_Option_Equilibrium
470 | Help_Option_Equilibrium_Credit
471 | Help_Option_Equilibrium_Debit
472 | Help_Option_Filter_Balance
473 | Help_Option_Filter_General_Ledger
474 | Help_Option_Filter_Posting
475 | Help_Option_Filter_Tag
476 | Help_Option_Filter_Transaction
477 | Help_Option_Help
478 | Help_Option_Input
479 | Help_Option_Lang
480 | Help_Option_Output
481 | Help_Option_Overwrite
482 | Help_Option_Tags_Tree
483 | Help_Option_Verbosity
484 | Help_Synopsis
485 instance Translate Help String where
486 translate EN t =
487 case t of
488 Help_Command_Balance -> "List final DEBITs, CREDITs and BALANCEs of ACCOUNTs"
489 Help_Command_General_Ledger -> "List DEBITs, CREDITs and BALANCEs of ACCOUNTs after each TRANSACTION"
490 Help_Command_Journal -> "List TRANSACTIONs"
491 Help_Command_Journals -> "List JOURNAL FILEs"
492 Help_Command_Stats -> "Show some statistics"
493 Help_Command_Tags -> "List TAGs"
494 Help_Option_Balance_Format -> "Select BALANCE output format"
495 Help_Option_Balance_Heritage -> "Propagate AMOUNTs to ascending ACCOUNTs"
496 Help_Option_Balance_Redundant -> "Also show ACCOUNTs with null AMOUNT or the same AMOUNTs than its descending ACCOUNT"
497 Help_Option_Balance_Total -> "Show transversal DEBIT, CREDIT, and BALANCE by UNIT"
498 Help_Option_Color -> "Colorize output"
499 Help_Option_Equilibrium -> "Specify the ACCOUNT equilibrating an opening or closing BALANCE"
500 Help_Option_Equilibrium_Credit -> "Like --eq but only when the AMOUNT is a CREDIT"
501 Help_Option_Equilibrium_Debit -> "Like --eq but only when the AMOUNT is a DEBIT"
502 Help_Option_Filter_Balance -> "Apply given FILTER_OF_BALANCE, multiple uses are joined with a logical AND"
503 Help_Option_Filter_General_Ledger -> "Apply given FILTER_OF_GENERAL_LEDGER, multiple uses are joined with a logical AND"
504 Help_Option_Filter_Posting -> "Apply given FILTER_OF_POSTING, multiple uses are joined with a logical AND"
505 Help_Option_Filter_Tag -> "Apply given FILTER_OF_TAG, multiple uses are joined with a logical AND"
506 Help_Option_Filter_Transaction -> "Apply given FILTER_OF_TRANSACTION, multiple uses are joined with a logical AND"
507 Help_Option_Help -> "Show this help"
508 Help_Option_Input -> "Read a JOURNAL from given FILE, multiple uses merge the data"
509 Help_Option_Lang -> "RFC1766 / ISO 639-1 language code (fr, en-GB, etc.)"
510 Help_Option_Output -> "Append output data to given FILE, multiple uses output to multiple FILEs"
511 Help_Option_Overwrite -> "Overwrite given FILE with output data, multiple uses overwrite to multiple FILEs"
512 Help_Option_Tags_Tree -> "Show TAGs as a tree"
513 Help_Option_Verbosity -> "Set verbosity level, or increment it when used multiple times"
514 Help_Synopsis -> "[OPTIONS] COMMAND [COMMAND_OPTIONS]"
515 translate FR t =
516 case t of
517 Help_Command_Balance -> "Liste les DÉBITs, CRÉDITs et SOLDEs finaux des COMPTEs"
518 Help_Command_General_Ledger -> "Liste les DÉBITs, CRÉDITs et SOLDEs des COMPTEs après chaque ÉCRITURE"
519 Help_Command_Journal -> "Liste les ÉCRITUREs"
520 Help_Command_Journals -> "Liste les FICHIERs des JOURNAUX"
521 Help_Command_Stats -> "Affiche quelques statistiques"
522 Help_Command_Tags -> "Liste les TAGs"
523 Help_Option_Balance_Format -> "Sélectionne le format de BALANCE en sortie"
524 Help_Option_Balance_Heritage -> "Propage les MONTANTs aux COMPTEs ascendants"
525 Help_Option_Balance_Redundant -> "Affiche également les COMPTEs dont le MONTANT est nul ou qui ont les mêmes MONTANTs que leur COMPTE descendant"
526 Help_Option_Balance_Total -> "Affiche les SOLDEs transversaux par UNITÉ"
527 Help_Option_Color -> "Colore la sortie"
528 Help_Option_Equilibrium -> "Indique le COMPTE d’équilibre pour une BALANCE d’ouverture ou de fermeture"
529 Help_Option_Equilibrium_Credit -> "Comme --eq mais seulement lorsque le MONTANT est un CRÉDIT"
530 Help_Option_Equilibrium_Debit -> "Comme --eq mais seulement lorsque le MONTANT est un DÉBIT"
531 Help_Option_Filter_Balance -> "Applique le FILTRE_DE_BALANCE donné, un usage multiple agit comme un ET logique"
532 Help_Option_Filter_General_Ledger -> "Applique le FILTRE_DE_GRAND_LIVRE donné, un usage multiple agit comme un ET logique"
533 Help_Option_Filter_Posting -> "Applique le FILTRE_DE_MOUVEMENT donné, un usage multiple agit comme un ET logique"
534 Help_Option_Filter_Tag -> "Applique le FILTRE_DE_TAG donné, un usage multiple agit comme un ET logique"
535 Help_Option_Filter_Transaction -> "Applique le FILTRE_D’ÉCRITURE donné, un usage multiple agit comme un ET logique"
536 Help_Option_Help -> "Affiche cette aide"
537 Help_Option_Input -> "Lit un JOURNAL dans le FICHIER donné, un usage multiple fusionne les données"
538 Help_Option_Lang -> "Code de langue RFC1766 / ISO 639-1 language code (fr, en-GB, etc.)"
539 Help_Option_Output -> "Ajoute la sortie au FICHIER donné, un usage multiple écrit dans plusieurs FICHIERs"
540 Help_Option_Overwrite -> "Écrase le FICHIER donné avec la sortie, un usage multiple écrase plusieurs FICHIERs"
541 Help_Option_Tags_Tree -> "Affiche les TAGs en arborescence"
542 Help_Option_Verbosity -> "Indique le niveau de verbosité, ou l’incrémente lorsque utilisé plusieurs fois"
543 Help_Synopsis -> "[PARAMÈTRES] COMMANDE [PARAMÈTRES_DE_COMMANDE]"
544
545 -- * Type 'Section'
546 data Section
547 = Section_Commands
548 | Section_Description
549 | Section_Syntax
550 | Section_Options
551 deriving (Eq, Show)
552 instance Translate Section String where
553 translate EN t =
554 case t of
555 Section_Commands -> "COMMANDS (use COMMAND --help for help on COMMAND)"
556 Section_Description -> "DESCRIPTION"
557 Section_Syntax -> "SYNTAX"
558 Section_Options -> "OPTIONS"
559 translate FR t =
560 case t of
561 Section_Commands -> "COMMANDES (utilisez COMMANDE --help pour une aide sur COMMANDE)"
562 Section_Description -> "DESCRIPTION"
563 Section_Syntax -> "SYNTAXE"
564 Section_Options -> "PARAMÈTRES"
565
566 -- * Type 'Title'
567 data Title
568 = Title_Account
569 | Title_Balance
570 | Title_Credit
571 | Title_Date
572 | Title_Debit
573 | Title_Description
574 | Title_Running_balance
575 | Title_Running_credit
576 | Title_Running_debit
577 instance Translate Title Text where
578 translate EN t =
579 case t of
580 Title_Account -> "Account"
581 Title_Balance -> "Balance"
582 Title_Credit -> "Credit"
583 Title_Date -> "Date"
584 Title_Debit -> "Debit"
585 Title_Description -> "Wording"
586 Title_Running_balance -> "Running balance"
587 Title_Running_credit -> "Running credit"
588 Title_Running_debit -> "Running debit"
589 translate FR t =
590 case t of
591 Title_Account -> "Compte"
592 Title_Balance -> "Solde"
593 Title_Credit -> "Crédit"
594 Title_Date -> "Date"
595 Title_Debit -> "Débit"
596 Title_Description -> "Libellé"
597 Title_Running_balance -> "Solde cumulé"
598 Title_Running_credit -> "Crédit cumulé"
599 Title_Running_debit -> "Débit cumulé"
600
601 -- * Type 'Type'
602 data Type
603 = Type_Account
604 | Type_File
605 | Type_File_Journal
606 | Type_Filter_Balance
607 | Type_Filter_General_Ledger
608 | Type_Filter_Posting
609 | Type_Filter_Tag
610 | Type_Filter_Transaction
611 | Type_Option
612 deriving (Eq, Show)
613 instance Translate Type String where
614 translate EN t =
615 case t of
616 Type_Account -> "ACCOUNT"
617 Type_File -> "FILE"
618 Type_File_Journal -> "FILE_OF_JOURNAL"
619 Type_Filter_Balance -> "FILTER_OF_BALANCE"
620 Type_Filter_General_Ledger -> "FILTER_OF_GENERAL_LEDGER"
621 Type_Filter_Posting -> "FILTER_OF_POSTING"
622 Type_Filter_Tag -> "FILTER_OF_TAG"
623 Type_Filter_Transaction -> "FILTER_OF_TRANSACTION"
624 Type_Option -> "OPTION"
625 translate FR t =
626 case t of
627 Type_Account -> "COMPTE"
628 Type_File -> "FICHIER"
629 Type_File_Journal -> "FICHIER_DE_JOURNAL"
630 Type_Filter_Balance -> "FILTRE_DE_BALANCE"
631 Type_Filter_General_Ledger -> "FILTRE_DE_GRAND_LIVRE"
632 Type_Filter_Posting -> "FILTRE_DE_MOUVEMENT"
633 Type_Filter_Tag -> "FILTRE_DE_TAG"
634 Type_Filter_Transaction -> "FILTRE_D’ÉCRITURE"
635 Type_Option -> "PARAMÈTRE"
636
637 -- * Type 'Write'
638 data Write
639 = Write_Debug
640 | Write_Error
641 instance Translate Write W.Doc where
642 translate EN t =
643 case t of
644 Write_Error -> "ERROR"
645 Write_Debug -> "DEBUG"
646 translate FR t =
647 case t of
648 Write_Error -> "ERREUR"
649 Write_Debug -> "DÉBUG"
650