diff --git a/src/hz_format.erl b/src/hz_format.erl index 94c8d86..f9598e8 100644 --- a/src/hz_format.erl +++ b/src/hz_format.erl @@ -5,7 +5,7 @@ -module(hz_format). -export([price/1, price/2, price/3, price/4, - read/1, read/2, +% read/1, read/2, price_to_string/1, string_to_price/1]). -spec price(Pucks) -> Formatted @@ -20,13 +20,13 @@ price(Pucks) -> -spec price(Style, Pucks) -> Formatted - when Style :: us | ch | jp | {Separator, Myriad}, - Separator :: $, | $. | $_, - Myriad :: 3 | 4, + when Style :: us | jp | metric | heresy | {Separator, Span}, + Separator :: $, | $_, + Span :: 3 | 4, Pucks :: integer(), Formatted :: string(). %% @doc -%% A convenient formatting function. +%% A money formatting function. %% @equiv price(gaju, Style, Pucks). price(Style, Pucks) -> @@ -35,9 +35,9 @@ price(Style, Pucks) -> -spec price(Unit, Style, Pucks) -> Formatted when Unit :: gaju | puck, - Style :: us | ch | jp | {Separator, Myriad}, - Separator :: $, | $. | $_, - Myriad :: 3 | 4, + Style :: us | jp | metric | heresy | {Separator, Span}, + Separator :: $, | $_, + Span :: 3 | 4, Pucks :: integer(), Formatted :: string(). %% @doc @@ -47,27 +47,24 @@ price(gaju, us, Pucks) -> western($,, $., 3, all, Pucks); price(puck, us, Pucks) -> western($,, 3, Pucks); -price(gaju, ch, Pucks) -> - western($., $,, 3, all, Pucks); -price(puck, ch, Pucks) -> - western($,, 3, Pucks); price(Unit, jp, Pucks) -> jp(Unit, all, Pucks); -price(gaju, {$., Myriad}, Pucks) -> - western($., $,, Myriad, all, Pucks); -price(gaju, {Separator, Myriad}, Pucks) -> - western(Separator, $., Myriad, all, Pucks); -price(puck, {Separator, Myriad}, Pucks) -> - western(Separator, Myriad, Pucks). - +price(Unit, metric, Pucks) -> + bestern(Unit, ranks(metric), all, Pucks); +price(Unit, heresy, Pucks) -> + bestern(Unit, ranks(heresy), all, Pucks); +price(gaju, {Separator, Span}, Pucks) -> + western(Separator, $., Span, all, Pucks); +price(puck, {Separator, Span}, Pucks) -> + western(Separator, Span, Pucks). -spec price(Unit, Style, Precision, Pucks) -> Serialized when Unit :: gaju | puck, - Style :: us | ch | jp | {Separator, Myriad}, + Style :: us | jp | metric | heresy | {Separator, Span}, Precision :: all | 0..18, - Separator :: $, | $. | $_, - Myriad :: 3 | 4, + Separator :: $, | $_, + Span :: 3 | 4, Pucks :: integer(), Serialized :: string(). %% @doc @@ -77,9 +74,6 @@ price(puck, {Separator, Myriad}, Pucks) -> %% price(gaju, us, 3, 123456789123456789123456789) -> %% "木123,456,789.123...". %% -%% price(gaju, ch, 3, 123456789123456789123456789) -> -%% "木123.456.789,123...". -%% %% price(gaju, us, 3, 123456789123000000000000000) -> %% "木123,456,789.123". %% @@ -89,9 +83,6 @@ price(puck, {Separator, Myriad}, Pucks) -> %% price(gaju, {$,, 3}, 6, 123456789123000000000000000) -> %% "木123,456,789.123" %% -%% price(gaju, {$., 3}, all, 123456789123456789123456789) -> -%% "木123.456.789,123.456.789.123.456.789" -%% %% price(gaju, {$_, 4}, 10, 123456789123456789123456789) -> %% "木1_2345_6789.1234_5678_91..." %% @@ -110,46 +101,46 @@ price(puck, {Separator, Myriad}, Pucks) -> price(gaju, us, Precision, Pucks) -> western($,, $., 3, Precision, Pucks); -price(gaju, ch, Precision, Pucks) -> - western($., $,, 3, Precision, Pucks); price(gaju, jp, Precision, Pucks) -> jp(gaju, Precision, Pucks); -price(gaju, {$., Myriad}, Precision, Pucks) -> - western($., $,, Myriad, Precision, Pucks); -price(gaju, {Separator, Myriad}, Precision, Pucks) -> - western(Separator, $., Myriad, Precision, Pucks); +price(gaju, metric, Precision, Pucks) -> + bestern(gaju, ranks(metric), Precision, Pucks); +price(gaju, legacy, Precision, Pucks) -> + bestern(gaju, ranks(heresy), Precision, Pucks); +price(gaju, {Separator, Span}, Precision, Pucks) -> + western(Separator, $., Span, Precision, Pucks); price(puck, us, _, Pucks) -> western($,, 3, Pucks); -price(puck, ch, _, Pucks) -> - western($., 3, Pucks); price(puck, jp, _, Pucks) -> jp(puck, all, Pucks); -price(puck, {Separator, Myriad}, _, Pucks) -> - western(Separator, Myriad, Pucks). +price(puck, metric, _, Pucks) -> + bestern(puck, ranks(metric), all, Pucks); +price(puck, legacy, _, Pucks) -> + bestern(puck, ranks(heresy), all, Pucks); +price(puck, {Separator, Span}, _, Pucks) -> + western(Separator, Span, Pucks). +western(Separator, Span, Pucks) when Pucks >= 0 -> + western2(Separator, Span, Pucks); +western(Separator, Span, Pucks) when Pucks < 0 -> + [$- | western2(Separator, Span, Pucks * -1)]. - -western(Separator, Myriad, Pucks) when Pucks >= 0 -> - western2(Separator, Myriad, Pucks); -western(Separator, Myriad, Pucks) when Pucks < 0 -> - [$- | western2(Separator, Myriad, Pucks * -1)]. - -western2(Separator, Myriad, Pucks) -> +western2(Separator, Span, Pucks) -> P = lists:reverse(integer_to_list(Pucks)), - [puck_mark() | separate(Separator, Myriad, P)]. + [puck_mark() | separate(Separator, Span, P)]. -western(Separator, Break, Myriad, Precision, Pucks) when Pucks >= 0 -> - western2(Separator, Break, Myriad, Precision, Pucks); -western(Separator, Break, Myriad, Precision, Pucks) when Pucks < 0 -> - [$- | western2(Separator, Break, Myriad, Precision, Pucks)]. +western(Separator, Break, Span, Precision, Pucks) when Pucks >= 0 -> + western2(Separator, Break, Span, Precision, Pucks); +western(Separator, Break, Span, Precision, Pucks) when Pucks < 0 -> + [$- | western2(Separator, Break, Span, Precision, Pucks)]. -western2(Separator, _, Myriad, 0, Pucks) -> +western2(Separator, _, Span, 0, Pucks) -> G = lists:reverse(integer_to_list(Pucks div one_gaju())), - [gaju_mark() | separate(Separator, Myriad, G)]; -western2(Separator, Break, Myriad, Precision, Pucks) -> + [gaju_mark() | separate(Separator, Span, G)]; +western2(Separator, Break, Span, Precision, Pucks) -> SP = integer_to_list(Pucks), Length = length(SP), Over18 = Length > 18, @@ -157,19 +148,19 @@ western2(Separator, Break, Myriad, Precision, Pucks) -> case {Over18, NoPucks} of {true, true} -> Gs = lists:reverse(lists:sublist(SP, Length - 18)), - [gaju_mark() | separate(Separator, Myriad, Gs)]; + [gaju_mark() | separate(Separator, Span, Gs)]; {true, false} -> {PChars, GChars} = lists:split(18, lists:reverse(SP)), - H = [gaju_mark() | separate(Separator, Myriad, GChars)], + H = [gaju_mark() | separate(Separator, Span, GChars)], {P, E} = decimal_pucks(Precision, lists:reverse(PChars)), - T = lists:reverse(separate(Separator, Myriad, P)), + T = lists:reverse(separate(Separator, Span, P)), lists:flatten([H, Break, T, E]); {false, true} -> [gaju_mark(), $0]; {false, false} -> PChars = lists:flatten(string:pad(SP, 18, leading, $0)), {P, E} = decimal_pucks(Precision, PChars), - T = lists:reverse(separate(Separator, Myriad, P)), + T = lists:reverse(separate(Separator, Span, P)), lists:flatten([gaju_mark(), $0, Break, T, E]) end. @@ -199,74 +190,159 @@ separate(S, P, N, [H | T], A) -> separate(S, P, N + 1, T, [H | A]). -jp(Unit, Precision, Pucks) when Pucks >= 0 -> - jp2(Unit, Precision, Pucks); -jp(Unit, Precision, Pucks) when Pucks < 0 -> - [$-, Formatted = jp2(Unit, Precision, Pucks * -1)]. +bestern(gaju, Ranks, Precision, Pucks) when Pucks >= 0 -> + [gaju_mark(), bestern2(gaju, Ranks, 3, Precision, Pucks)]; +bestern(gaju, Ranks, Precision, Pucks) when Pucks < 0 -> + [$-, gaju_mark(), bestern2(gaju, Ranks, 3, Precision, Pucks * -1)]; +bestern(puck, Ranks, Precision, Pucks) when Pucks >= 0 -> + [puck_mark(), bestern2(puck, Ranks, 3, Precision, Pucks)]; +bestern(puck, Ranks, Precision, Pucks) when Pucks < 0 -> + [$-, puck_mark(), bestern2(puck, Ranks, 3, Precision, Pucks * -1)]. -jp2(gaju, 0, Pucks) -> +jp(Unit, Precision, Pucks) when Pucks >= 0 -> + bestern2(Unit, ranks(jp), 4, Precision, Pucks); +jp(Unit, Precision, Pucks) when Pucks < 0 -> + [$-, bestern2(Unit, ranks(jp), 4, Precision, Pucks * -1)]. + +bestern2(gaju, Ranks, Span, 0, Pucks) -> G = lists:reverse(integer_to_list(Pucks div one_gaju())), - myriad4(gaju_mark(), h, G); -jp2(gaju, all, Pucks) -> - H = jp(gaju, 0, Pucks), + case Span of + 3 -> period(" G", Ranks, G); + 4 -> myriad(gaju_mark(), Ranks, G) + end; +bestern2(gaju, Ranks, Span, all, Pucks) -> P = lists:flatten(string:pad(integer_to_list(Pucks rem one_gaju()), 18, leading, $0)), - T = myriad4("", l, lists:reverse(P)), + {H, T} = + case Span of + 3 -> {bestern2(gaju, Ranks, 3, 0, Pucks), period(" P", Ranks, lists:reverse(P))}; + 4 -> {jp(gaju, 0, Pucks), myriad(puck_mark(), Ranks, lists:reverse(P))} + end, lists:flatten([H, " ", T]); -jp2(gaju, Precision, Pucks) -> - H = jp(gaju, 0, Pucks), +bestern2(gaju, Ranks, Span, Precision, Pucks) -> P = lists:flatten(string:pad(integer_to_list(Pucks rem one_gaju()), 18, leading, $0)), + H = + case Span of + 3 -> bestern2(gaju, Ranks, 3, 0, Pucks); + 4 -> jp(gaju, 0, Pucks) + end, Digits = min(Precision, 18), T = - case length(P) > Digits of - true -> - []; + case length(P) < Digits of false -> ReverseP = lists:reverse(lists:sublist(P, Digits)), PuckingString = lists:flatten(string:pad(ReverseP, 18, leading, $0)), case lists:all(fun(C) -> C =:= $0 end, PuckingString) of - false -> myriad4(puck_mark(), l, PuckingString); - true -> "" - end + false -> + case Span of + 3 -> period(" P", Ranks, PuckingString); + 4 -> myriad(puck_mark(), Ranks, PuckingString) + end; + true -> + "" + end; + true -> + [] end, - T = myriad4("", l, lists:reverse(P)), lists:flatten([H, " ", T]); -jp2(puck, all, Pucks) -> +bestern2(puck, Ranks, Span, all, Pucks) -> P = lists:reverse(integer_to_list(Pucks)), case lists:all(fun(C) -> C =:= $0 end, P) of - false -> myriad4(puck_mark(), h, P); - true -> [$0, puck_mark()] + false -> + case Span of + 3 -> period(" P", Ranks, P); + 4 -> myriad(puck_mark(), Ranks, P) + end; + true -> + case Span of + 3 -> [$0, " P"]; + 4 -> [$0, puck_mark()] + end end; -jp2(puck, Precision, Pucks) -> +bestern2(puck, Ranks, Span, Precision, Pucks) -> Digits = min(Precision, 18), P = lists:flatten(string:pad(integer_to_list(Pucks), 18, leading, $0)), case length(P) < Digits of true -> - [$0, puck_mark()]; + case Span of + 3 -> [$0, " P"]; + 4 -> [$0, puck_mark()] + end; false -> PucksToGive = lists:sublist(P, Digits), PuckingString = lists:flatten(string:pad(lists:reverse(PucksToGive), 18, leading, $0)), case lists:all(fun(C) -> C =:= $0 end, PuckingString) of - false -> myriad4(puck_mark(), h, PuckingString); - true -> [$0, puck_mark()] + false -> + case Span of + 3 -> period(" P", Ranks, PuckingString); + 4 -> myriad(puck_mark(), Ranks, PuckingString) + end; + true -> + case Span of + 3 -> [$0, " P"]; + 4 -> [$0, puck_mark()] + end end end. -myriad4(Symbol, Segment, [$0, $0, $0, $0 | PT]) -> - rank4(ranks(Segment), PT, [Symbol]); -myriad4(Symbol, Segment, [P4, $0, $0, $0 | PT]) -> - rank4(ranks(Segment), PT, [P4, Symbol]); -myriad4(Symbol, Segment, [P4, P3, $0, $0 | PT]) -> - rank4(ranks(Segment), PT, [P3, P4, Symbol]); -myriad4(Symbol, Segment, [P4, P3, P2, $0 | PT]) -> - rank4(ranks(Segment), PT, [P2, P3, P4, Symbol]); -myriad4(Symbol, Segment, [P4, P3, P2, P1 | PT]) -> - rank4(ranks(Segment), PT, [P1, P2, P3, P4, Symbol]); -myriad4(Symbol, _, [P4]) -> +period(Symbol, Ranks, [$0, $0, $0 | PT]) -> + rank3(Ranks, PT, [Symbol]); +period(Symbol, Ranks, [P3, $0, $0 | PT]) -> + rank3(Ranks, PT, [P3, Symbol]); +period(Symbol, Ranks, [P3, P2, $0 | PT]) -> + rank3(Ranks, PT, [P2, P3, Symbol]); +period(Symbol, Ranks, [P3, P2, P1 | PT]) -> + rank3(Ranks, PT, [P1, P2, P3, Symbol]); +period(Symbol, _, [P3]) -> + [P3, Symbol]; +period(Symbol, _, [P3, P2]) -> + [P2, P3, Symbol]. + +rank3([_ | RT], [$0, $0, $0 | PT], A) -> + rank3(RT, PT, A); +rank3([RH | RT], [P3, $0, $0 | PT], A) -> + rank3(RT, PT, [P3, RH | A]); +rank3([RH | RT], [P3, P2, $0 | PT], A) -> + rank3(RT, PT, [P2, P3, RH | A]); +rank3([RH | RT], [P3, P2, P1 | PT], A) -> + rank3(RT, PT, [P1, P2, P3, RH | A]); +rank3(_, [$0, $0, $0], A) -> + A; +rank3(_, [$0, $0], A) -> + A; +rank3(_, [$0], A) -> + A; +rank3(_, [], A) -> + A; +rank3([RH | _], [P3, $0, $0], A) -> + [P3, RH | A]; +rank3([RH | _], [P3, $0], A) -> + [P3, RH | A]; +rank3([RH | _], [P3], A) -> + [P3, RH | A]; +rank3([RH | _], [P3, P2, $0], A) -> + [P2, P3, RH | A]; +rank3([RH | _], [P3, P2], A) -> + [P2, P3, RH | A]; +rank3([RH | _], [P3, P2, P1], A) -> + [P1, P2, P3, RH | A]. + + +myriad(Symbol, Ranks, [$0, $0, $0, $0 | PT]) -> + rank4(Ranks, PT, [Symbol]); +myriad(Symbol, Ranks, [P4, $0, $0, $0 | PT]) -> + rank4(Ranks, PT, [P4, Symbol]); +myriad(Symbol, Ranks, [P4, P3, $0, $0 | PT]) -> + rank4(Ranks, PT, [P3, P4, Symbol]); +myriad(Symbol, Ranks, [P4, P3, P2, $0 | PT]) -> + rank4(Ranks, PT, [P2, P3, P4, Symbol]); +myriad(Symbol, Ranks, [P4, P3, P2, P1 | PT]) -> + rank4(Ranks, PT, [P1, P2, P3, P4, Symbol]); +myriad(Symbol, _, [P4]) -> [P4, Symbol]; -myriad4(Symbol, _, [P4, P3]) -> +myriad(Symbol, _, [P4, P3]) -> [P3, P4, Symbol]; -myriad4(Symbol, _, [P4, P3, P2]) -> +myriad(Symbol, _, [P4, P3, P2]) -> [P2, P3, P4, Symbol]. rank4([_ | RT], [$0, $0, $0, $0 | PT], A) -> @@ -310,11 +386,12 @@ rank4([RH | _], [P4, P3, P2], A) -> rank4([RH | _], [P4, P3, P2, P1], A) -> [P1, P2, P3, P4, RH | A]. -ranks(h) -> +ranks(jp) -> "万億兆京垓秭穣溝澗正載極"; -ranks(l) -> -% "曼戌弒俿咳". - "満億照鏡咳". +ranks(metric) -> + ["k ", "m ", "g ", "t ", "p ", "e ", "z ", "y ", "r ", "Q "]; +ranks(heresy) -> + ["k ", "m ", "b ", "t ", "q ", "e ", "z ", "y ", "r ", "Q "]. gaju_mark() -> $木. @@ -324,190 +401,188 @@ puck_mark() -> $本. one_gaju() -> 1_000_000_000_000_000_000. --spec read(Format) -> Result - when Format :: string(), - Result :: {ok, Pucks} | {error, Reason}, - Pucks :: integer(), - Reason :: {badarg, Partial :: string(), Rest :: term()} - | {incomplete, Partial :: string(), Rest :: binary()} - | format. -%% @doc -%% Convery any valid string formatted representation and output a value in pucks. -%% This routine can fail in the special case of `ch' style formatting with a single -%% comma and/or a single period in it, as this can trigger misinterpretation as `us' -%% style. When in doubt, always call `read/2' with a style specified. - -read(Format) -> - case assess_style(string:trim(Format)) of - us -> read(us, Format); - ch -> read(ch, Format); - jp -> read(jp, Format); - Error -> Error - end. - -assess_style([H1, H2 | Numbers]) - when H1 =:= $木 orelse H1 =:= $本 orelse H2 =:= $木 orelse H2 =:= $本 -> - case count($., Numbers) > 1 of - false -> us; - true -> ch - end; -assess_style(Format) -> - case lists:member($木, Format) orelse lists:member($本, Format) of - true -> jp; - false -> {error, format} - end. - -count(Char, String) -> count(Char, String, 0). - -count(C, [C | T], A) -> count(C, T, A + 1); -count(C, [_ | T], A) -> count(C, T, A); -count(_, [], A) -> A. - - --spec read(Style, Format) -> Result - when Style :: us | ch | jp | undefined, - Format :: string(), - Result :: {ok, Pucks} | {error, Reason}, - Pucks :: integer(), - Reason :: {badarg, Partial :: string(), Rest :: term()} - | {incomplete, Partial :: string(), Rest :: binary()} - | format. -%% @doc -%% Convert any valid string formatted representation and output a value in pucks. -%% Note that this function is deliberately a bit too permissive in the case of -%% western formatting, stripping all non-halfwidth digit characters on the high -%% and low sides of the format once the break (decimal) character is identified -%% and sign is determined. That is to say, there are many ways to feed this wacky -%% strings and get a number out of it, so be aware. - -read(Style, Format) -> - case unicode:characters_to_list(Format) of - String when is_list(String) -> - Trimmed = string:trim(String), - read2(Style, Trimmed); - {error, Partial, Rest} -> - {error, {badarg, Partial, Rest}}; - Incomplete -> - {error, Incomplete} - end. - -read2(us, Format) -> - read_western($., Format); -read2(ch, Format) -> - read_western($,, Format); -read2(jp, Format) -> - read_jp(Format); -read2(undefined, Format) -> - read(Format). - -read_western(Break, [$-, Format]) -> - case read_western2(Break, Format) of - {ok, Pucks} -> {ok, Pucks * -1}; - Error -> Error - end; -read_western(Break, Format) -> - read_western2(Break, Format). - -read_western2(Break, Format) -> - case string:split(Format, [Break], all) of - [[], L] -> read_western3(0, L); - [H, []] -> read_western3(H, 0); - [H, L] -> read_western3(H, L); - [H] -> read_western3(H, 0); - _ -> {error, format} - end. - -read_western3(0, L) -> - read_l(L); -read_western3(H, 0) -> - case read_h(H) of - {ok, Gajus} -> {ok, Gajus * one_gaju()}; - Error -> Error - end; -read_western3(H, L) -> - Gajus = read_h(H), - Pucks = read_l(L), - {ok, (Gajus * one_gaju()) + Pucks}. - -read_h(S) -> - case lists:filter(fun is_numchar/1, S) of - [] -> 0; - F -> list_to_integer(Filtered) - end. - -read_l(L) -> - case lists:filter(fun is_numchar/1, S) of - [] -> 0; - F -> list_to_integer(lists:flatten(string:pad(F, 18, trailing, $0))) - end. - -is_numchar(C) -> $0 =< C andalso C =< $9. - -read_jp([$-, Format]) -> - read_jp_neg(Format); -read_jp([$-, Format]) -> - read_jp_neg(Format); -read_jp(Format) -> - read_jp2(Format). - -read_jp_neg(Format) -> - case read_jp2(Format) of - {ok, Pucks} -> {ok, Pucks * -1}; - Error -> Error - end. - -read_jp2(Format) -> - case segment_jp(Format) of - {ok, Segments} -> assemble_jp(Segments); - Error -> Error - end. - -segment_jp(Format) -> - case string:split(Format, [gaju_mark()], all) of - [Gajus, Pucks] -> - case read_segment(Gajus) of - {ok, GajuSegments} -> - case read_segment(Pucks) of - {ok, PuckSegments} -> {ok, GajuSegments, PuckSegments}; - Error -> Error - end; - Error -> - Error - end; - [Gajus] -> - case read_segment(Gajus) of - {ok, GajuSegments} -> {ok, GajuSegments, ["0"]}; - Error -> Error - end; - [] -> - {ok, ["0"], ["0"]}; - _ -> - {error, format} - end. - -read_segment([C | T], R, A) when $0 =< C andalso C =< $9 -> - N = C - $0, - read_segment(T, R, [NA); -read_segment([C | T], R, A) when $0 =< C andalso C =< $9 -> - - - -assemble_jp({GajuSegments, PuckSegments}) -> - GajuString = lists:flatten(lists:map(fun expand_jp_myriad/1, GajuSegments)), - PuckString = lists:flatten(lists:map(fun expand_jp_myriad/1, PuckDegments)), - {ok, integer_to_list(lists:append(GajuString, PuckString))}. -assemble_jp(PuckSegments) -> - PuckString = lists:flatten(lists:map(fun expand_jp_myriad/1, PuckDegments)), - {ok, integer_to_list(PuckString)}. - -expand_jp_myriad(String) -> - string:pad(String, 4, leading, $0). - - -hw_jp_numchar(C) when $0 =< C andalso C =< $9 -> - C - $0; -hw_jp_numchar(C) -> - C. +%-spec read(Format) -> Result +% when Format :: string(), +% Result :: {ok, Pucks} | {error, Reason}, +% Pucks :: integer(), +% Reason :: {badarg, Partial :: string(), Rest :: term()} +% | {incomplete, Partial :: string(), Rest :: binary()} +% | format. +%%% @doc +%%% Convery any valid string formatted representation and output a value in pucks. +%%% This routine can fail in the special case of `ch' style formatting with a single +%%% comma and/or a single period in it, as this can trigger misinterpretation as `us' +%%% style. When in doubt, always call `read/2' with a style specified. +% +%read(Format) -> +% case assess_style(string:trim(Format)) of +% us -> read(us, Format); +% ch -> read(ch, Format); +% jp -> read(jp, Format); +% Error -> Error +% end. +% +%assess_style([H1, H2 | Numbers]) +% when H1 =:= $木 orelse H1 =:= $本 orelse H2 =:= $木 orelse H2 =:= $本 -> +% case count($., Numbers) > 1 of +% false -> us; +% true -> ch +% end; +%assess_style(Format) -> +% case lists:member($木, Format) orelse lists:member($本, Format) of +% true -> jp; +% false -> {error, format} +% end. +% +%count(Char, String) -> count(Char, String, 0). +% +%count(C, [C | T], A) -> count(C, T, A + 1); +%count(C, [_ | T], A) -> count(C, T, A); +%count(_, [], A) -> A. +% +% +%-spec read(Style, Format) -> Result +% when Style :: us | jp | metric | legacy | undefined, +% Format :: string(), +% Result :: {ok, Pucks} | {error, Reason}, +% Pucks :: integer(), +% Reason :: {badarg, Partial :: string(), Rest :: term()} +% | {incomplete, Partial :: string(), Rest :: binary()} +% | format. +%%% @doc +%%% Convert any valid string formatted representation and output a value in pucks. +%%% Note that this function is deliberately a bit too permissive in the case of +%%% western formatting, stripping all non-halfwidth digit characters on the high +%%% and low sides of the format once the break (decimal) character is identified +%%% and sign is determined. That is to say, there are many ways to feed this wacky +%%% strings and get a number out of it, so be aware. +% +%read(Style, Format) -> +% case unicode:characters_to_list(Format) of +% String when is_list(String) -> +% Trimmed = string:trim(String), +% read2(Style, Trimmed); +% {error, Partial, Rest} -> +% {error, {badarg, Partial, Rest}}; +% Incomplete -> +% {error, Incomplete} +% end. +% +%read2(us, Format) -> +% read_western($., Format); +%read2(jp, Format) -> +% read_jp(Format); +%read2(undefined, Format) -> +% read(Format). +% +%read_western(Break, [$-, Format]) -> +% case read_western2(Break, Format) of +% {ok, Pucks} -> {ok, Pucks * -1}; +% Error -> Error +% end; +%read_western(Break, Format) -> +% read_western2(Break, Format). +% +%read_western2(Break, Format) -> +% case string:split(Format, [Break], all) of +% [[], L] -> read_western3(0, L); +% [H, []] -> read_western3(H, 0); +% [H, L] -> read_western3(H, L); +% [H] -> read_western3(H, 0); +% _ -> {error, format} +% end. +% +%read_western3(0, L) -> +% read_l(L); +%read_western3(H, 0) -> +% case read_h(H) of +% {ok, Gajus} -> {ok, Gajus * one_gaju()}; +% Error -> Error +% end; +%read_western3(H, L) -> +% Gajus = read_h(H), +% Pucks = read_l(L), +% {ok, (Gajus * one_gaju()) + Pucks}. +% +%read_h(S) -> +% case lists:filter(fun is_numchar/1, S) of +% [] -> 0; +% F -> list_to_integer(Filtered) +% end. +% +%read_l(L) -> +% case lists:filter(fun is_numchar/1, S) of +% [] -> 0; +% F -> list_to_integer(lists:flatten(string:pad(F, 18, trailing, $0))) +% end. +% +%is_numchar(C) -> $0 =< C andalso C =< $9. +% +%read_jp([$-, Format]) -> +% read_jp_neg(Format); +%read_jp([$-, Format]) -> +% read_jp_neg(Format); +%read_jp(Format) -> +% read_jp2(Format). +% +%read_jp_neg(Format) -> +% case read_jp2(Format) of +% {ok, Pucks} -> {ok, Pucks * -1}; +% Error -> Error +% end. +% +%read_jp2(Format) -> +% case segment_jp(Format) of +% {ok, Segments} -> assemble_jp(Segments); +% Error -> Error +% end. +% +%segment_jp(Format) -> +% case string:split(Format, [gaju_mark()], all) of +% [Gajus, Pucks] -> +% case read_segment(Gajus) of +% {ok, GajuSegments} -> +% case read_segment(Pucks) of +% {ok, PuckSegments} -> {ok, GajuSegments, PuckSegments}; +% Error -> Error +% end; +% Error -> +% Error +% end; +% [Gajus] -> +% case read_segment(Gajus) of +% {ok, GajuSegments} -> {ok, GajuSegments, ["0"]}; +% Error -> Error +% end; +% [] -> +% {ok, ["0"], ["0"]}; +% _ -> +% {error, format} +% end. +% +%read_segment([C | T], R, A) when $0 =< C andalso C =< $9 -> +% N = C - $0, +% read_segment(T, R, [NA); +%read_segment([C | T], R, A) when $0 =< C andalso C =< $9 -> +% +% +% +%assemble_jp({GajuSegments, PuckSegments}) -> +% GajuString = lists:flatten(lists:map(fun expand_jp_myriad/1, GajuSegments)), +% PuckString = lists:flatten(lists:map(fun expand_jp_myriad/1, PuckDegments)), +% {ok, integer_to_list(lists:append(GajuString, PuckString))}. +%assemble_jp(PuckSegments) -> +% PuckString = lists:flatten(lists:map(fun expand_jp_myriad/1, PuckDegments)), +% {ok, integer_to_list(PuckString)}. +% +%expand_jp_myriad(String) -> +% string:pad(String, 4, leading, $0). +% +% +%hw_jp_numchar(C) when $0 =< C andalso C =< $9 -> +% C - $0; +%hw_jp_numchar(C) -> +% C. -spec price_to_string(Pucks) -> Gajus