aboutsummaryrefslogtreecommitdiff
path: root/src/number.ml
blob: cdd9ef887fe27fe840f85cad898dbf6161a5907f (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
type parseInsideTextResult = { before : string; number : float; after : string }

let execRegex (regex : Js.Re.t) (str : string) : string option Js.Array.t =
  match Js.Re.exec_ regex str with
  | Some result -> Js.Array.map Js.toOption (Js.Re.captures result)
  | None -> [||]

let parseInsideText (str : string) : parseInsideTextResult option =
  match execRegex [%re "/^([^\\d]*)(\\d+)((\\.|,)(\\d+))?(.*)/"] str with
  | [| _; Some before; Some intPart; _; _; decPart; Some after |] ->
      Some
        {
          before;
          number =
            Js.Float.fromString
              ( intPart
              ^ Belt.Option.mapWithDefault decPart "" (fun str -> "." ^ str) );
          after;
        }
  | _ -> None

type parseResult = { number : float; remaining : string }

let parse (str : string) : parseResult option =
  match parseInsideText str with
  | Some parseResult ->
      if parseResult.before == "" then
        Some { number = parseResult.number; remaining = parseResult.after }
      else None
  | _ -> None

type numberElement = { element : Dom.element; numberInput : Dom.element }

let prettyPrint (number : float) : string =
  let strNumber = Js.Float.toString number in
  match Js.String.split "." strNumber with
  | [| intPart; decPart |] ->
      intPart ^ "," ^ Js.String.slice ~from:0 ~to_:2 decPart
  | _ -> strNumber

let createElement (tag : string) (content : parseInsideTextResult) :
    numberElement =
  let numberInput =
    DomUtils.h "input"
      [| ("class", "g-Number"); ("value", prettyPrint content.number) |]
      [| DomUtils.TextChild "" |]
  in
  {
    element =
      DomUtils.h tag [||]
        [|
          DomUtils.TextChild content.before;
          DomUtils.ElemChild numberInput;
          DomUtils.TextChild content.after;
        |];
    numberInput;
  }