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
open Base
open Liquid_syntax
open Syntax
open Tools
let fi = Float.to_int
let identity _ params = List.hd_exn params
let err t = Error ("Liquid Error: " ^ t)
let errc t c = Error (
Core.sprintf "Liquid Error: %s, Params: %s" t
(List.map c ~f:Debug.value_as_string |> join_by_comma)
)
let ok v = Ok v
let ok_num v = Ok (Number v)
let ok_str v = Ok (String v)
let ok_list v = Ok (List v)
type whitespace_remover = Beginning | End | Both
let remove_whitespace remover text =
let exp = match remover with
| Beginning -> ~/"^\\s+"
| End -> ~/"\\s+$"
| Both -> ~/"^\\s+|\\s+$" in
Re2.rewrite_exn exp ~template:"" text
let pick_at_by_op op _ = function
| Number a :: Number b :: _ -> Number (if op a b then a else b) |> ok
| other -> errc "at_most/at_least accepts 2 numbers" other
let apply_op op _ = function
| Nil :: Number b :: _ -> Number (op 0. b) |> ok
| Number a :: Number b :: _ ->
Number (op a b) |> ok
| other -> errc "operator accepts 2 numbers" other
let lst key =
let lookup_key = function
| Object obj -> (match Obj.find_opt key obj with Some x -> x | _ -> Nil)
| _ -> Nil
in
List.map lst ~f:lookup_key
type weight_units = Grams | Kilograms | Pounds | Ounces
let weight_unit_as_string = function
| Grams -> "g"
| Kilograms -> "kg"
| Pounds -> "lbs"
| Ounces -> "ozs"
let parse_weight_unit = function
| "g" | "gs" | "grams" | "gram" -> Grams
| "kg" | "kgs" | "kilograms" | "kilogram" -> Kilograms
| "lb" | "lbs" | "pounds" | "pound" -> Pounds
| "oz" | "ozs" | "ounces" | "ounce" -> Ounces
| _ -> Pounds
let format_thousands_int n =
let i = n |> Int.to_string |> String.rev in
let r = List.init (String.length i) ~f:(String.get i) in
let ts = Char.to_string in
let rec aux = function
| a :: b :: c :: tl -> [ts c ^ ts b ^ ts a] @ aux tl
| a :: b :: tl -> [ts b ^ ts a] @ aux tl
| a :: tl -> [ts a] @ aux tl
| _ -> []
in
aux r
|> List.rev
|> String.concat ~sep:","
let format_thousands_float n =
let dec =
match nth (n |> Float.to_string |> String.split ~on:'.') 1 with
| "" -> "0"
| other -> other
in
format_thousands_int (n |> Float.to_int) ^ "." ^ dec
let format_money_number n =
let pieces =
Float.round_decimal n ~decimal_digits:2
|> Float.to_string
|> String.split ~on:'.'
in
let fs = n |> Float.to_int |> format_thousands_int in
let sd = nth pieces 1 in
let clean_sd = match String.length sd with 0 -> "00" | 1 -> sd ^ "0" | _ -> sd in
fs ^ "." ^ clean_sd
let format_money_symbol (currency_info: Settings.currency_info) num =
currency_info.symbol ^ format_money_number num
let format_money_currency (currency_info: Settings.currency_info) num =
currency_info.symbol ^ format_money_number num ^ " " ^ currency_info.abbr
let format_money_symbol_no_zeros (currency_info: Settings.currency_info) num =
currency_info.symbol ^ (Float.to_int num |> format_thousands_int)