package tiny_appkits
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
Application engines from scratch: a spreadsheet, rich text, paint, draw, CAD, editors and more
Install
dune-project
Dependency
Authors
Maintainers
Sources
0.3.6.tar.gz
md5=7c636383d146d30ac6f2fa234a6253c8
sha512=c79f3823c5f8f57e5038eb640d487c61168b84aa07c61999d6622ef9fd0c890e2b03b4c6a7cdbbe9352a49e25dda00ac7bb14693cee8e3d7beeed251351a2af0
doc/src/tiny_appkits.appkit_money/Money.ml.html
Source file Money.ml
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(* Claude Code * * Copyright (C) 2026 Yoann Padioleau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * (LGPL) as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. *) (* See Money.mli *) type cents = int let digits s = s <> "" && String.for_all (fun c -> c >= '0' && c <= '9') s let of_string (s : string) : cents option = let s = String.concat "" (String.split_on_char ',' (String.trim s)) in let negative, s = if s <> "" && s.[0] = '-' then (true, String.sub s 1 (String.length s - 1)) else (false, s) in let s = if s <> "" && s.[0] = '$' then String.sub s 1 (String.length s - 1) else s in let whole, fraction = match String.split_on_char '.' s with | [ w ] -> (w, "") | [ w; f ] -> (w, f) | _ -> ("", "x") in let whole = if whole = "" && fraction <> "" then "0" else whole in if digits whole && (fraction = "" || (digits fraction && String.length fraction <= 2)) then let fraction = fraction ^ String.make (2 - String.length fraction) '0' in let c = (int_of_string whole * 100) + int_of_string fraction in Some (if negative then -c else c) else None let to_string (c : cents) : string = let a = abs c in let whole = string_of_int (a / 100) in (* a comma every three digits, counted from the right *) let n = String.length whole in let buf = Buffer.create (n + 4) in String.iteri (fun i ch -> if i > 0 && (n - i) mod 3 = 0 then Buffer.add_char buf ','; Buffer.add_char buf ch) whole; Printf.sprintf "%s%s.%02d" (if c < 0 then "-" else "") (Buffer.contents buf) (a mod 100) let ones = [| ""; "one"; "two"; "three"; "four"; "five"; "six"; "seven"; "eight"; "nine"; "ten"; "eleven"; "twelve"; "thirteen"; "fourteen"; "fifteen"; "sixteen"; "seventeen"; "eighteen"; "nineteen" |] let tens = [| ""; ""; "twenty"; "thirty"; "forty"; "fifty"; "sixty"; "seventy"; "eighty"; "ninety" |] (* 0 to 999: "one hundred twenty-three" *) let below_thousand n = let hundreds = n / 100 and rest = n mod 100 in let rest_words = if rest < 20 then ones.(rest) else if rest mod 10 = 0 then tens.(rest / 10) else tens.(rest / 10) ^ "-" ^ ones.(rest mod 10) in String.concat " " (List.filter (( <> ) "") [ (if hundreds > 0 then ones.(hundreds) ^ " hundred" else ""); rest_words ]) (* in groups of three digits, each with its scale's name *) let rec in_words n = let scales = [ (1_000_000_000, "billion"); (1_000_000, "million"); (1_000, "thousand") ] in match List.find_opt (fun (s, _) -> n >= s) scales with | Some (s, name) -> let rest = n mod s in in_words (n / s) ^ " " ^ name ^ if rest > 0 then " " ^ in_words rest else "" | None -> below_thousand n let words (c : cents) : string = let c = abs c in let dollars = if c / 100 = 0 then "zero" else in_words (c / 100) in Printf.sprintf "%s%s and %02d/100" (String.uppercase_ascii (String.sub dollars 0 1)) (String.sub dollars 1 (String.length dollars - 1)) (c mod 100)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>