[m-rev.] for review: add string.format_table/2
Ian MacLarty
maclarty at cs.mu.OZ.AU
Thu Feb 3 21:47:52 AEDT 2005
For review by anyone.
Estimated hours taken: 3
Branches: main
Add a function to the string module to generate a formatted text table.
library/string.m
Add format_table/2 which generates a formatted text table from
a list of columns.
tests/general/string_test.exp
tests/general/string_test.m
Test the new function.
Index: library/string.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/string.m,v
retrieving revision 1.227
diff -u -r1.227 string.m
--- library/string.m 3 Feb 2005 09:06:36 -0000 1.227
+++ library/string.m 3 Feb 2005 10:43:14 -0000
@@ -667,6 +667,28 @@
; c(char).
%-----------------------------------------------------------------------------%
+
+:- type justified_column
+ ---> left(list(string))
+ ; right(list(string)).
+
+ % format_table(Columns, Seperator) = Table
+ % format_table/2 takes a list of columns and a column seperator
+ % and returns a formatted table, where each field in each column
+ % has been aligned and fields are seperated with Seperator.
+ % A newline character is inserted between each row.
+ %
+ % For example:
+ %
+ % format_table([right(["a", "bb", "ccc"]), left(["1", "22", "333"])],
+ % " * ")
+ % would return the table:
+ % a * 1
+ % bb * 22
+ % ccc * 333
+ %
+:- func string__format_table(list(justified_column), string) = string.
+
%-----------------------------------------------------------------------------%
:- implementation.
@@ -4616,6 +4638,61 @@
char_list_equal(Xs, Ys).
%------------------------------------------------------------------------------%
+
+string__format_table(Columns, Seperator) = Table :-
+ MaxWidths = list.map(find_max_length, Columns),
+ PaddedColumns = list.map_corresponding(pad_column, MaxWidths, Columns),
+ (
+ PaddedColumns = [PaddedHead | PaddedTail],
+ Rows = list.foldl(list.map_corresponding(
+ string.join_rev_columns(
+ Seperator)), PaddedTail, PaddedHead)
+ ;
+ PaddedColumns = [],
+ Rows = []
+ ),
+ Table = string.join_list("\n", Rows).
+
+:- func join_rev_columns(string, string, string) = string.
+
+join_rev_columns(Seperator, Col1, Col2) = Col2 ++ Seperator ++ Col1.
+
+:- func find_max_length(justified_column) = int.
+
+find_max_length(left(Strings)) = MaxWidth :-
+ list.foldl(max_str_length, Strings, {0, ""}, {MaxWidth, _}).
+find_max_length(right(Strings)) = MaxWidth :-
+ list.foldl(max_str_length, Strings, {0, ""}, {MaxWidth, _}).
+
+:- func pad_column(int, justified_column) = list(string).
+
+pad_column(Width, left(Strings)) = list.map(string.rpad(' ', Width), Strings).
+pad_column(Width, right(Strings)) = list.map(string.lpad(' ', Width), Strings).
+
+:- func rpad(char, int, string) = string.
+
+rpad(Chr, N, Str) = string.pad_right(Str, Chr, N).
+
+:- func lpad(char, int, string) = string.
+
+lpad(Chr, N, Str) = string.pad_left(Str, Chr, N).
+
+:- pred max_str_length(string::in, {int, string}::in, {int, string}::out)
+ is det.
+
+max_str_length(Str, {PrevMaxLen, PrevMaxStr}, {MaxLen, MaxStr}) :-
+ Length = string.length(Str),
+ (
+ Length > PrevMaxLen
+ ->
+ MaxLen = Length,
+ MaxStr = Str
+ ;
+ MaxLen = PrevMaxLen,
+ MaxStr = PrevMaxStr
+ ).
+
+%-----------------------------------------------------------------------------%
:- end_module string.
Index: tests/general/string_test.exp
===================================================================
RCS file: /home/mercury1/repository/tests/general/string_test.exp,v
retrieving revision 1.2
diff -u -r1.2 string_test.exp
--- tests/general/string_test.exp 3 Feb 2005 09:06:37 -0000 1.2
+++ tests/general/string_test.exp 3 Feb 2005 10:41:44 -0000
@@ -14,3 +14,6 @@
Five f's: fffff
Five f's and five dots: fffff.....
Five dashes, five f's and five dots: -----fffff.....
+aaa|1111111| 1,300,000.00
+b | | 9,999.00
+cc | 333|123,456,789.99
Index: tests/general/string_test.m
===================================================================
RCS file: /home/mercury1/repository/tests/general/string_test.m,v
retrieving revision 1.4
diff -u -r1.4 string_test.m
--- tests/general/string_test.m 3 Feb 2005 09:06:37 -0000 1.4
+++ tests/general/string_test.m 3 Feb 2005 10:41:13 -0000
@@ -56,7 +56,12 @@
{ string__pad_right(FiveFs, '.', 10, FsAndDots) },
write_message("Five f's and five dots: ", FsAndDots),
{ string__pad_left(FsAndDots, '-', 15, DashesFsAndDots) },
- write_message("Five dashes, five f's and five dots: ", DashesFsAndDots),
+ write_message("Five dashes, five f's and five dots: ",
+ DashesFsAndDots),
+ { Table = string__format_table([left(["aaa", "b", "cc"]),
+ right(["1111111", "", "333"]), right(["1,300,000.00",
+ "9,999.00", "123,456,789.99"])], "|") ++ "\n" },
+ write_string(Table),
[].
:- pred write_message(string, string, io__state, io__state).
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list