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.