formatters #14

Merged
zxq9 merged 15 commits from formatters into master 2025-12-22 11:14:20 +09:00
Showing only changes of commit b219d0f784 - Show all commits

View File

@ -5,7 +5,7 @@
-module(hz_format). -module(hz_format).
-export([price/1, price/2, price/3, price/4, -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]). price_to_string/1, string_to_price/1]).
-spec price(Pucks) -> Formatted -spec price(Pucks) -> Formatted
@ -20,13 +20,13 @@ price(Pucks) ->
-spec price(Style, Pucks) -> Formatted -spec price(Style, Pucks) -> Formatted
when Style :: us | ch | jp | {Separator, Myriad}, when Style :: us | jp | metric | heresy | {Separator, Span},
Separator :: $, | $. | $_, Separator :: $, | $_,
Myriad :: 3 | 4, Span :: 3 | 4,
Pucks :: integer(), Pucks :: integer(),
Formatted :: string(). Formatted :: string().
%% @doc %% @doc
%% A convenient formatting function. %% A money formatting function.
%% @equiv price(gaju, Style, Pucks). %% @equiv price(gaju, Style, Pucks).
price(Style, Pucks) -> price(Style, Pucks) ->
@ -35,9 +35,9 @@ price(Style, Pucks) ->
-spec price(Unit, Style, Pucks) -> Formatted -spec price(Unit, Style, Pucks) -> Formatted
when Unit :: gaju | puck, when Unit :: gaju | puck,
Style :: us | ch | jp | {Separator, Myriad}, Style :: us | jp | metric | heresy | {Separator, Span},
Separator :: $, | $. | $_, Separator :: $, | $_,
Myriad :: 3 | 4, Span :: 3 | 4,
Pucks :: integer(), Pucks :: integer(),
Formatted :: string(). Formatted :: string().
%% @doc %% @doc
@ -47,27 +47,24 @@ price(gaju, us, Pucks) ->
western($,, $., 3, all, Pucks); western($,, $., 3, all, Pucks);
price(puck, us, Pucks) -> price(puck, us, Pucks) ->
western($,, 3, Pucks); western($,, 3, Pucks);
price(gaju, ch, Pucks) ->
western($., $,, 3, all, Pucks);
price(puck, ch, Pucks) ->
western($,, 3, Pucks);
price(Unit, jp, Pucks) -> price(Unit, jp, Pucks) ->
jp(Unit, all, Pucks); jp(Unit, all, Pucks);
price(gaju, {$., Myriad}, Pucks) -> price(Unit, metric, Pucks) ->
western($., $,, Myriad, all, Pucks); bestern(Unit, ranks(metric), all, Pucks);
price(gaju, {Separator, Myriad}, Pucks) -> price(Unit, heresy, Pucks) ->
western(Separator, $., Myriad, all, Pucks); bestern(Unit, ranks(heresy), all, Pucks);
price(puck, {Separator, Myriad}, Pucks) -> price(gaju, {Separator, Span}, Pucks) ->
western(Separator, Myriad, Pucks). western(Separator, $., Span, all, Pucks);
price(puck, {Separator, Span}, Pucks) ->
western(Separator, Span, Pucks).
-spec price(Unit, Style, Precision, Pucks) -> Serialized -spec price(Unit, Style, Precision, Pucks) -> Serialized
when Unit :: gaju | puck, when Unit :: gaju | puck,
Style :: us | ch | jp | {Separator, Myriad}, Style :: us | jp | metric | heresy | {Separator, Span},
Precision :: all | 0..18, Precision :: all | 0..18,
Separator :: $, | $. | $_, Separator :: $, | $_,
Myriad :: 3 | 4, Span :: 3 | 4,
Pucks :: integer(), Pucks :: integer(),
Serialized :: string(). Serialized :: string().
%% @doc %% @doc
@ -77,9 +74,6 @@ price(puck, {Separator, Myriad}, Pucks) ->
%% price(gaju, us, 3, 123456789123456789123456789) -> %% price(gaju, us, 3, 123456789123456789123456789) ->
%% "木123,456,789.123...". %% "木123,456,789.123...".
%% %%
%% price(gaju, ch, 3, 123456789123456789123456789) ->
%% "木123.456.789,123...".
%%
%% price(gaju, us, 3, 123456789123000000000000000) -> %% price(gaju, us, 3, 123456789123000000000000000) ->
%% "木123,456,789.123". %% "木123,456,789.123".
%% %%
@ -89,9 +83,6 @@ price(puck, {Separator, Myriad}, Pucks) ->
%% price(gaju, {$,, 3}, 6, 123456789123000000000000000) -> %% price(gaju, {$,, 3}, 6, 123456789123000000000000000) ->
%% "木123,456,789.123" %% "木123,456,789.123"
%% %%
%% price(gaju, {$., 3}, all, 123456789123456789123456789) ->
%% "木123.456.789,123.456.789.123.456.789"
%%
%% price(gaju, {$_, 4}, 10, 123456789123456789123456789) -> %% price(gaju, {$_, 4}, 10, 123456789123456789123456789) ->
%% "木1_2345_6789.1234_5678_91..." %% "木1_2345_6789.1234_5678_91..."
%% %%
@ -110,46 +101,46 @@ price(puck, {Separator, Myriad}, Pucks) ->
price(gaju, us, Precision, Pucks) -> price(gaju, us, Precision, Pucks) ->
western($,, $., 3, Precision, Pucks); western($,, $., 3, Precision, Pucks);
price(gaju, ch, Precision, Pucks) ->
western($., $,, 3, Precision, Pucks);
price(gaju, jp, Precision, Pucks) -> price(gaju, jp, Precision, Pucks) ->
jp(gaju, Precision, Pucks); jp(gaju, Precision, Pucks);
price(gaju, {$., Myriad}, Precision, Pucks) -> price(gaju, metric, Precision, Pucks) ->
western($., $,, Myriad, Precision, Pucks); bestern(gaju, ranks(metric), Precision, Pucks);
price(gaju, {Separator, Myriad}, Precision, Pucks) -> price(gaju, legacy, Precision, Pucks) ->
western(Separator, $., Myriad, Precision, Pucks); bestern(gaju, ranks(heresy), Precision, Pucks);
price(gaju, {Separator, Span}, Precision, Pucks) ->
western(Separator, $., Span, Precision, Pucks);
price(puck, us, _, Pucks) -> price(puck, us, _, Pucks) ->
western($,, 3, Pucks); western($,, 3, Pucks);
price(puck, ch, _, Pucks) ->
western($., 3, Pucks);
price(puck, jp, _, Pucks) -> price(puck, jp, _, Pucks) ->
jp(puck, all, Pucks); jp(puck, all, Pucks);
price(puck, {Separator, Myriad}, _, Pucks) -> price(puck, metric, _, Pucks) ->
western(Separator, Myriad, 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)].
western2(Separator, Span, Pucks) ->
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) ->
P = lists:reverse(integer_to_list(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 -> western(Separator, Break, Span, Precision, Pucks) when Pucks >= 0 ->
western2(Separator, Break, Myriad, Precision, Pucks); western2(Separator, Break, Span, Precision, Pucks);
western(Separator, Break, Myriad, Precision, Pucks) when Pucks < 0 -> western(Separator, Break, Span, Precision, Pucks) when Pucks < 0 ->
[$- | western2(Separator, Break, Myriad, Precision, Pucks)]. [$- | 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())), G = lists:reverse(integer_to_list(Pucks div one_gaju())),
[gaju_mark() | separate(Separator, Myriad, G)]; [gaju_mark() | separate(Separator, Span, G)];
western2(Separator, Break, Myriad, Precision, Pucks) -> western2(Separator, Break, Span, Precision, Pucks) ->
SP = integer_to_list(Pucks), SP = integer_to_list(Pucks),
Length = length(SP), Length = length(SP),
Over18 = Length > 18, Over18 = Length > 18,
@ -157,19 +148,19 @@ western2(Separator, Break, Myriad, Precision, Pucks) ->
case {Over18, NoPucks} of case {Over18, NoPucks} of
{true, true} -> {true, true} ->
Gs = lists:reverse(lists:sublist(SP, Length - 18)), Gs = lists:reverse(lists:sublist(SP, Length - 18)),
[gaju_mark() | separate(Separator, Myriad, Gs)]; [gaju_mark() | separate(Separator, Span, Gs)];
{true, false} -> {true, false} ->
{PChars, GChars} = lists:split(18, lists:reverse(SP)), {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)), {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]); lists:flatten([H, Break, T, E]);
{false, true} -> {false, true} ->
[gaju_mark(), $0]; [gaju_mark(), $0];
{false, false} -> {false, false} ->
PChars = lists:flatten(string:pad(SP, 18, leading, $0)), PChars = lists:flatten(string:pad(SP, 18, leading, $0)),
{P, E} = decimal_pucks(Precision, PChars), {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]) lists:flatten([gaju_mark(), $0, Break, T, E])
end. end.
@ -199,74 +190,159 @@ separate(S, P, N, [H | T], A) ->
separate(S, P, N + 1, T, [H | A]). separate(S, P, N + 1, T, [H | A]).
jp(Unit, Precision, Pucks) when Pucks >= 0 -> bestern(gaju, Ranks, Precision, Pucks) when Pucks >= 0 ->
jp2(Unit, Precision, Pucks); [gaju_mark(), bestern2(gaju, Ranks, 3, Precision, Pucks)];
jp(Unit, Precision, Pucks) when Pucks < 0 -> bestern(gaju, Ranks, Precision, Pucks) when Pucks < 0 ->
[$, Formatted = jp2(Unit, Precision, Pucks * -1)]. [$-, 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())), G = lists:reverse(integer_to_list(Pucks div one_gaju())),
myriad4(gaju_mark(), h, G); case Span of
jp2(gaju, all, Pucks) -> 3 -> period(" G", Ranks, G);
H = jp(gaju, 0, Pucks), 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)), 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]); lists:flatten([H, " ", T]);
jp2(gaju, Precision, Pucks) -> bestern2(gaju, Ranks, Span, Precision, Pucks) ->
H = jp(gaju, 0, Pucks),
P = lists:flatten(string:pad(integer_to_list(Pucks rem one_gaju()), 18, leading, $0)), 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), Digits = min(Precision, 18),
T = T =
case length(P) > Digits of case length(P) < Digits of
true ->
[];
false -> false ->
ReverseP = lists:reverse(lists:sublist(P, Digits)), ReverseP = lists:reverse(lists:sublist(P, Digits)),
PuckingString = lists:flatten(string:pad(ReverseP, 18, leading, $0)), PuckingString = lists:flatten(string:pad(ReverseP, 18, leading, $0)),
case lists:all(fun(C) -> C =:= $0 end, PuckingString) of case lists:all(fun(C) -> C =:= $0 end, PuckingString) of
false -> myriad4(puck_mark(), l, PuckingString); false ->
true -> "" case Span of
end 3 -> period(" P", Ranks, PuckingString);
4 -> myriad(puck_mark(), Ranks, PuckingString)
end;
true ->
""
end;
true ->
[]
end, end,
T = myriad4("", l, lists:reverse(P)),
lists:flatten([H, " ", T]); lists:flatten([H, " ", T]);
jp2(puck, all, Pucks) -> bestern2(puck, Ranks, Span, all, Pucks) ->
P = lists:reverse(integer_to_list(Pucks)), P = lists:reverse(integer_to_list(Pucks)),
case lists:all(fun(C) -> C =:= $0 end, P) of case lists:all(fun(C) -> C =:= $0 end, P) of
false -> myriad4(puck_mark(), h, P); false ->
true -> [$0, puck_mark()] case Span of
3 -> period(" P", Ranks, P);
4 -> myriad(puck_mark(), Ranks, P)
end; end;
jp2(puck, Precision, Pucks) -> true ->
case Span of
3 -> [$0, " P"];
4 -> [$0, puck_mark()]
end
end;
bestern2(puck, Ranks, Span, Precision, Pucks) ->
Digits = min(Precision, 18), Digits = min(Precision, 18),
P = lists:flatten(string:pad(integer_to_list(Pucks), 18, leading, $0)), P = lists:flatten(string:pad(integer_to_list(Pucks), 18, leading, $0)),
case length(P) < Digits of case length(P) < Digits of
true -> true ->
[$0, puck_mark()]; case Span of
3 -> [$0, " P"];
4 -> [$0, puck_mark()]
end;
false -> false ->
PucksToGive = lists:sublist(P, Digits), PucksToGive = lists:sublist(P, Digits),
PuckingString = lists:flatten(string:pad(lists:reverse(PucksToGive), 18, leading, $0)), PuckingString = lists:flatten(string:pad(lists:reverse(PucksToGive), 18, leading, $0)),
case lists:all(fun(C) -> C =:= $0 end, PuckingString) of case lists:all(fun(C) -> C =:= $0 end, PuckingString) of
false -> myriad4(puck_mark(), h, PuckingString); false ->
true -> [$0, puck_mark()] 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
end. end.
myriad4(Symbol, Segment, [$0, $0, $0, $0 | PT]) -> period(Symbol, Ranks, [$0, $0, $0 | PT]) ->
rank4(ranks(Segment), PT, [Symbol]); rank3(Ranks, PT, [Symbol]);
myriad4(Symbol, Segment, [P4, $0, $0, $0 | PT]) -> period(Symbol, Ranks, [P3, $0, $0 | PT]) ->
rank4(ranks(Segment), PT, [P4, Symbol]); rank3(Ranks, PT, [P3, Symbol]);
myriad4(Symbol, Segment, [P4, P3, $0, $0 | PT]) -> period(Symbol, Ranks, [P3, P2, $0 | PT]) ->
rank4(ranks(Segment), PT, [P3, P4, Symbol]); rank3(Ranks, PT, [P2, P3, Symbol]);
myriad4(Symbol, Segment, [P4, P3, P2, $0 | PT]) -> period(Symbol, Ranks, [P3, P2, P1 | PT]) ->
rank4(ranks(Segment), PT, [P2, P3, P4, Symbol]); rank3(Ranks, PT, [P1, P2, P3, Symbol]);
myriad4(Symbol, Segment, [P4, P3, P2, P1 | PT]) -> period(Symbol, _, [P3]) ->
rank4(ranks(Segment), PT, [P1, P2, P3, P4, Symbol]); [P3, Symbol];
myriad4(Symbol, _, [P4]) -> 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]; [P4, Symbol];
myriad4(Symbol, _, [P4, P3]) -> myriad(Symbol, _, [P4, P3]) ->
[P3, P4, Symbol]; [P3, P4, Symbol];
myriad4(Symbol, _, [P4, P3, P2]) -> myriad(Symbol, _, [P4, P3, P2]) ->
[P2, P3, P4, Symbol]. [P2, P3, P4, Symbol].
rank4([_ | RT], [$0, $0, $0, $0 | PT], A) -> 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) -> rank4([RH | _], [P4, P3, P2, P1], A) ->
[P1, P2, P3, P4, RH | 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() -> $木. gaju_mark() -> $木.
@ -324,190 +401,188 @@ puck_mark() -> $本.
one_gaju() -> 1_000_000_000_000_000_000. one_gaju() -> 1_000_000_000_000_000_000.
-spec read(Format) -> Result %-spec read(Format) -> Result
when Format :: string(), % when Format :: string(),
Result :: {ok, Pucks} | {error, Reason}, % Result :: {ok, Pucks} | {error, Reason},
Pucks :: integer(), % Pucks :: integer(),
Reason :: {badarg, Partial :: string(), Rest :: term()} % Reason :: {badarg, Partial :: string(), Rest :: term()}
| {incomplete, Partial :: string(), Rest :: binary()} % | {incomplete, Partial :: string(), Rest :: binary()}
| format. % | format.
%% @doc %%% @doc
%% Convery any valid string formatted representation and output a value in pucks. %%% 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 %%% 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' %%% 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. %%% style. When in doubt, always call `read/2' with a style specified.
%
read(Format) -> %read(Format) ->
case assess_style(string:trim(Format)) of % case assess_style(string:trim(Format)) of
us -> read(us, Format); % us -> read(us, Format);
ch -> read(ch, Format); % ch -> read(ch, Format);
jp -> read(jp, Format); % jp -> read(jp, Format);
Error -> Error % Error -> Error
end. % end.
%
assess_style([H1, H2 | Numbers]) %assess_style([H1, H2 | Numbers])
when H1 =:= $木 orelse H1 =:= $本 orelse H2 =:= $木 orelse H2 =:= $本 -> % when H1 =:= $木 orelse H1 =:= $本 orelse H2 =:= $木 orelse H2 =:= $本 ->
case count($., Numbers) > 1 of % case count($., Numbers) > 1 of
false -> us; % false -> us;
true -> ch % true -> ch
end; % end;
assess_style(Format) -> %assess_style(Format) ->
case lists:member($木, Format) orelse lists:member($本, Format) of % case lists:member($木, Format) orelse lists:member($本, Format) of
true -> jp; % true -> jp;
false -> {error, format} % false -> {error, format}
end. % end.
%
count(Char, String) -> count(Char, String, 0). %count(Char, String) -> count(Char, String, 0).
%
count(C, [C | T], A) -> count(C, T, A + 1); %count(C, [C | T], A) -> count(C, T, A + 1);
count(C, [_ | T], A) -> count(C, T, A); %count(C, [_ | T], A) -> count(C, T, A);
count(_, [], A) -> A. %count(_, [], A) -> A.
%
%
-spec read(Style, Format) -> Result %-spec read(Style, Format) -> Result
when Style :: us | ch | jp | undefined, % when Style :: us | jp | metric | legacy | undefined,
Format :: string(), % Format :: string(),
Result :: {ok, Pucks} | {error, Reason}, % Result :: {ok, Pucks} | {error, Reason},
Pucks :: integer(), % Pucks :: integer(),
Reason :: {badarg, Partial :: string(), Rest :: term()} % Reason :: {badarg, Partial :: string(), Rest :: term()}
| {incomplete, Partial :: string(), Rest :: binary()} % | {incomplete, Partial :: string(), Rest :: binary()}
| format. % | format.
%% @doc %%% @doc
%% Convert any valid string formatted representation and output a value in pucks. %%% 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 %%% 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 %%% 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 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 %%% 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. %%% strings and get a number out of it, so be aware.
%
read(Style, Format) -> %read(Style, Format) ->
case unicode:characters_to_list(Format) of % case unicode:characters_to_list(Format) of
String when is_list(String) -> % String when is_list(String) ->
Trimmed = string:trim(String), % Trimmed = string:trim(String),
read2(Style, Trimmed); % read2(Style, Trimmed);
{error, Partial, Rest} -> % {error, Partial, Rest} ->
{error, {badarg, Partial, Rest}}; % {error, {badarg, Partial, Rest}};
Incomplete -> % Incomplete ->
{error, Incomplete} % {error, Incomplete}
end. % end.
%
read2(us, Format) -> %read2(us, Format) ->
read_western($., Format); % read_western($., Format);
read2(ch, Format) -> %read2(jp, Format) ->
read_western($,, Format); % read_jp(Format);
read2(jp, Format) -> %read2(undefined, Format) ->
read_jp(Format); % read(Format).
read2(undefined, Format) -> %
read(Format). %read_western(Break, [$-, Format]) ->
% case read_western2(Break, Format) of
read_western(Break, [$-, Format]) -> % {ok, Pucks} -> {ok, Pucks * -1};
case read_western2(Break, Format) of % Error -> Error
{ok, Pucks} -> {ok, Pucks * -1}; % end;
Error -> Error %read_western(Break, Format) ->
end; % read_western2(Break, Format).
read_western(Break, Format) -> %
read_western2(Break, Format). %read_western2(Break, Format) ->
% case string:split(Format, [Break], all) of
read_western2(Break, Format) -> % [[], L] -> read_western3(0, L);
case string:split(Format, [Break], all) of % [H, []] -> read_western3(H, 0);
[[], L] -> read_western3(0, L); % [H, L] -> read_western3(H, L);
[H, []] -> read_western3(H, 0); % [H] -> read_western3(H, 0);
[H, L] -> read_western3(H, L); % _ -> {error, format}
[H] -> read_western3(H, 0); % end.
_ -> {error, format} %
end. %read_western3(0, L) ->
% read_l(L);
read_western3(0, L) -> %read_western3(H, 0) ->
read_l(L); % case read_h(H) of
read_western3(H, 0) -> % {ok, Gajus} -> {ok, Gajus * one_gaju()};
case read_h(H) of % Error -> Error
{ok, Gajus} -> {ok, Gajus * one_gaju()}; % end;
Error -> Error %read_western3(H, L) ->
end; % Gajus = read_h(H),
read_western3(H, L) -> % Pucks = read_l(L),
Gajus = read_h(H), % {ok, (Gajus * one_gaju()) + Pucks}.
Pucks = read_l(L), %
{ok, (Gajus * one_gaju()) + Pucks}. %read_h(S) ->
% case lists:filter(fun is_numchar/1, S) of
read_h(S) -> % [] -> 0;
case lists:filter(fun is_numchar/1, S) of % F -> list_to_integer(Filtered)
[] -> 0; % end.
F -> list_to_integer(Filtered) %
end. %read_l(L) ->
% case lists:filter(fun is_numchar/1, S) of
read_l(L) -> % [] -> 0;
case lists:filter(fun is_numchar/1, S) of % F -> list_to_integer(lists:flatten(string:pad(F, 18, trailing, $0)))
[] -> 0; % end.
F -> list_to_integer(lists:flatten(string:pad(F, 18, trailing, $0))) %
end. %is_numchar(C) -> $0 =< C andalso C =< $9.
%
is_numchar(C) -> $0 =< C andalso C =< $9. %read_jp([$-, Format]) ->
% read_jp_neg(Format);
read_jp([$-, Format]) -> %read_jp([$, Format]) ->
read_jp_neg(Format); % read_jp_neg(Format);
read_jp([$, Format]) -> %read_jp(Format) ->
read_jp_neg(Format); % read_jp2(Format).
read_jp(Format) -> %
read_jp2(Format). %read_jp_neg(Format) ->
% case read_jp2(Format) of
read_jp_neg(Format) -> % {ok, Pucks} -> {ok, Pucks * -1};
case read_jp2(Format) of % Error -> Error
{ok, Pucks} -> {ok, Pucks * -1}; % end.
Error -> Error %
end. %read_jp2(Format) ->
% case segment_jp(Format) of
read_jp2(Format) -> % {ok, Segments} -> assemble_jp(Segments);
case segment_jp(Format) of % Error -> Error
{ok, Segments} -> assemble_jp(Segments); % end.
Error -> Error %
end. %segment_jp(Format) ->
% case string:split(Format, [gaju_mark()], all) of
segment_jp(Format) -> % [Gajus, Pucks] ->
case string:split(Format, [gaju_mark()], all) of % case read_segment(Gajus) of
[Gajus, Pucks] -> % {ok, GajuSegments} ->
case read_segment(Gajus) of % case read_segment(Pucks) of
{ok, GajuSegments} -> % {ok, PuckSegments} -> {ok, GajuSegments, PuckSegments};
case read_segment(Pucks) of % Error -> Error
{ok, PuckSegments} -> {ok, GajuSegments, PuckSegments}; % end;
Error -> Error % Error ->
end; % Error
Error -> % end;
Error % [Gajus] ->
end; % case read_segment(Gajus) of
[Gajus] -> % {ok, GajuSegments} -> {ok, GajuSegments, ["0"]};
case read_segment(Gajus) of % Error -> Error
{ok, GajuSegments} -> {ok, GajuSegments, ["0"]}; % end;
Error -> Error % [] ->
end; % {ok, ["0"], ["0"]};
[] -> % _ ->
{ok, ["0"], ["0"]}; % {error, format}
_ -> % end.
{error, format} %
end. %read_segment([C | T], R, A) when $0 =< C andalso C =< $9 ->
% N = C - $0,
read_segment([C | T], R, A) when $0 =< C andalso C =< $9 -> % read_segment(T, R, [NA);
N = C - $0, %read_segment([C | T], R, A) when $ =< C andalso C =< $ ->
read_segment(T, R, [NA); %
read_segment([C | T], R, A) when $ =< C andalso C =< $ -> %
%
%assemble_jp({GajuSegments, PuckSegments}) ->
% GajuString = lists:flatten(lists:map(fun expand_jp_myriad/1, GajuSegments)),
assemble_jp({GajuSegments, PuckSegments}) -> % PuckString = lists:flatten(lists:map(fun expand_jp_myriad/1, PuckDegments)),
GajuString = lists:flatten(lists:map(fun expand_jp_myriad/1, GajuSegments)), % {ok, integer_to_list(lists:append(GajuString, PuckString))}.
PuckString = lists:flatten(lists:map(fun expand_jp_myriad/1, PuckDegments)), %assemble_jp(PuckSegments) ->
{ok, integer_to_list(lists:append(GajuString, PuckString))}. % PuckString = lists:flatten(lists:map(fun expand_jp_myriad/1, PuckDegments)),
assemble_jp(PuckSegments) -> % {ok, integer_to_list(PuckString)}.
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).
expand_jp_myriad(String) -> %
string:pad(String, 4, leading, $0). %
%hw_jp_numchar(C) when $ =< C andalso C =< $ ->
% C - $;
hw_jp_numchar(C) when $ =< C andalso C =< $ -> %hw_jp_numchar(C) ->
C - $; % C.
hw_jp_numchar(C) ->
C.
-spec price_to_string(Pucks) -> Gajus -spec price_to_string(Pucks) -> Gajus