RosettaCodeData/Task/Align-columns/Oberon/align-columns.oberon
2023-07-01 13:44:08 -04:00

107 lines
2.6 KiB
Text

MODULE Columns;
IMPORT
NPCT:Tools,
Object,
Out;
TYPE
Parts = ARRAY 32 OF STRING;
Formatter = PROCEDURE (s: STRING; len: LONGINT): STRING;
VAR
lines: ARRAY 6 OF STRING;
words: ARRAY 6 OF Parts;
columnWidth: ARRAY 128 OF INTEGER;
lineIdx: INTEGER;
(*
* Size: returns de number of words in a line
*)
PROCEDURE Size(p: Parts): INTEGER;
VAR
i: INTEGER;
BEGIN
i := 0;
WHILE (i < LEN(p)) & (p[i] # NIL) DO
INC(i);
END;
RETURN i
END Size;
(*
* Max: returns maximum number of words in the lines
*)
PROCEDURE Max(w: ARRAY OF Parts): INTEGER;
VAR
i, max, resp: INTEGER;
BEGIN
i := 0;resp := 0;
WHILE (i < LEN(w)) DO
max := Size(w[i]);
IF (max > resp) THEN resp := max END;
INC(i)
END;
RETURN resp;
END Max;
(*
* MaxColumnWidth: returns the maximum width of a column
*)
PROCEDURE MaxColumnWidth(w: ARRAY OF Parts;column: INTEGER): INTEGER;
VAR
line,max: LONGINT;
BEGIN
line := 0;
max := MIN(INTEGER);
WHILE (line < LEN(w)) DO;
IF (w[line,column] # NIL) & (w[line,column](Object.String8).length > max) THEN max := w[line,column](Object.String8).length END;
INC(line)
END;
RETURN SHORT(max)
END MaxColumnWidth;
(*
* PrintWords: prints the words in 'w' using the formatter passed in 'format'
*)
PROCEDURE PrintWords(w: ARRAY OF Parts; format: Formatter);
VAR
i,j: INTEGER;
BEGIN
i := 0;
WHILE (i < LEN(words)) DO
j := 0;
WHILE (j < Max(words)) & (words[i,j] # NIL) DO
Out.Object(format(words[i,j],columnWidth[j] + 1));
INC(j)
END;
Out.Ln;
INC(i)
END;
Out.Ln
END PrintWords;
BEGIN
lines[0] := "Given$a$text$file$of$many$lines,$where$fields$within$a$line$";
lines[1] := "are$delineated$by$a$single$'dollar'$character,$write$a$program";
lines[2] := "that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$";
lines[3] := "column$are$separated$by$at$least$one$space.";
lines[4] := "Further,$allow$for$each$word$in$a$column$to$be$either$left$";
lines[5] := "justified,$right$justified,$or$center$justified$within$its$column.";
(* Split line in words *)
lineIdx := 0;
WHILE lineIdx < LEN(lines) DO
Tools.Split(lines[lineIdx],"$",words[lineIdx]);
INC(lineIdx)
END;
(* Calculate width of the column *)
lineIdx := 0;
WHILE (lineIdx < Max(words)) DO
columnWidth[lineIdx] := MaxColumnWidth(words,lineIdx);
INC(lineIdx)
END;
(* Print Results *)
PrintWords(words,Tools.AdjustLeft);
PrintWords(words,Tools.AdjustCenter);
PrintWords(words,Tools.AdjustRight);
END Columns.