diff --git a/src/lib/format.pl b/src/lib/format.pl index 3fd28fb6..fd2a9816 100644 --- a/src/lib/format.pl +++ b/src/lib/format.pl @@ -1,5 +1,5 @@ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Written 2020, 2021 by Markus Triska (triska@metalevel.at) + Written 2020, 2021, 2022 by Markus Triska (triska@metalevel.at) Part of Scryer Prolog. This library provides the nonterminal format_//2 to describe @@ -28,6 +28,9 @@ if N is 0 or omitted, no decimal point is used. ~ND like ~Nd, separating digits to the left of the decimal point in groups of three, using the character "," (comma) + ~NU like ~ND, using "_" (underscore) to separate groups of digits + ~NL format an integer so that at most N digits appear on a line. + If N is 0 or omitted, it defaults to 72. ~Nr where N is an integer between 2 and 36: format the next argument, which must be an integer, in radix N. The characters "a" to "z" are used for radices 10 to 36. @@ -200,14 +203,22 @@ cells([~|Fs0], Args0, Tab, Es, VNs) --> cells([~|Fs0], Args0, Tab, Es, VNs) --> { numeric_argument(Fs0, Num, ['D'|Fs], Args0, [Arg|Args]) }, !, - { number_chars(Num, NCs), - phrase(("~",seq(NCs),"d"), FStr), - phrase(format_(FStr, [Arg]), Cs0), - phrase(upto_what(Bs0, .), Cs0, Ds), - reverse(Bs0, Bs1), - phrase(groups_of_three(Bs1), Bs2), - reverse(Bs2, Bs), - append(Bs, Ds, Cs) }, + { separate_digits_fractional(Arg, ',', Num, Cs) }, + cells(Fs, Args, Tab, [chars(Cs)|Es], VNs). +cells([~|Fs0], Args0, Tab, Es, VNs) --> + { numeric_argument(Fs0, Num, ['U'|Fs], Args0, [Arg|Args]) }, + !, + { separate_digits_fractional(Arg, '_', Num, Cs) }, + cells(Fs, Args, Tab, [chars(Cs)|Es], VNs). +cells([~|Fs0], Args0, Tab, Es, VNs) --> + { numeric_argument(Fs0, Num0, ['L'|Fs], Args0, [Arg|Args]) }, + !, + { ( Num0 =:= 0 -> + Num = 72 + ; Num = Num0 + ), + phrase(format_("~d", [Arg]), Cs0), + phrase(split_lines_width(Cs0, Num), Cs) }, cells(Fs, Args, Tab, [chars(Cs)|Es], VNs). cells([~,i|Fs], [_|Args], Tab, Es, VNs) --> !, cells(Fs, Args, Tab, Es, VNs). @@ -312,12 +323,30 @@ Cs = [a,b,c], Rest = [~,t,e,s,t]. Cs = [a,b,c], Rest = []. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +separate_digits_fractional(Arg, Sep, Num, Cs) :- + number_chars(Num, NCs), + phrase(("~",seq(NCs),"d"), FStr), + phrase(format_(FStr, [Arg]), Cs0), + phrase(upto_what(Bs0, .), Cs0, Ds), + reverse(Bs0, Bs1), + phrase(groups_of_three(Bs1,Sep), Bs2), + reverse(Bs2, Bs), + append(Bs, Ds, Cs). + upto_what([], W), [W] --> [W], !. upto_what([C|Cs], W) --> [C], !, upto_what(Cs, W). upto_what([], _) --> []. -groups_of_three([A,B,C,D|Rs]) --> !, [A,B,C], ",", groups_of_three([D|Rs]). -groups_of_three(Ls) --> seq(Ls). +groups_of_three([A,B,C,D|Rs], Sep) --> !, [A,B,C,Sep], groups_of_three([D|Rs], Sep). +groups_of_three(Ls, _) --> seq(Ls). + +split_lines_width(Cs, Num) --> + ( { length(Prefix, Num), + append(Prefix, [R|Rs], Cs) } -> + seq(Prefix), "_\n", + split_lines_width([R|Rs], Num) + ; seq(Cs) + ). cell(From, To, Es0) --> ( { Es0 == [] } -> []