Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
helpers.ml1 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 112open 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 (* NOTE: For incr, decr to work, it must tolerate nil value. Maybe create incr_op func? *) 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 extract_key_from_object_list lst key = let lookup_key = function | Object obj -> ( match Object.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 (* TODO: Add more currency *) (* 12345 -> 54321 *) (* 1234567 *) 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)