Skip to content

Instantly share code, notes, and snippets.

@tinchodias
Created March 30, 2022 01:15
Show Gist options
  • Save tinchodias/0f99be3cecbe3fc5ed93dea90c877fd5 to your computer and use it in GitHub Desktop.
Save tinchodias/0f99be3cecbe3fc5ed93dea90c877fd5 to your computer and use it in GitHub Desktop.
printSep := [ :stream :colLengths |
stream nextPut: $+.
colLengths do: [ :len |
stream
next: len put: $-;
nextPut: $+ ].
stream cr ].
paddedRow := [ :row :expectedSize |
row size >= expectedSize
ifTrue: [ row ]
ifFalse: [ row, (Array new: expectedSize - row size withAll: '') ] ].
printRows := [ :stream :rows :box :justifyEach |
| maxNumCols maxLengths |
maxNumCols := (rows collect: [ :row | row size ]) max.
maxLengths := rows
inject: (Array new: maxNumCols withAll: 0)
into: [ :maxLengthsSoFar :row |
maxLengthsSoFar
with: (paddedRow value: row value: maxNumCols)
collect: [ :maxLen :col | maxLen max: col size ] ].
rows do: [ :row |
| first |
box ifTrue: [ printSep value: stream value: maxLengths ].
first := true.
(box
ifTrue: [ paddedRow value: row value: maxLengths size ]
ifFalse: [ row ])
with: (box
ifTrue: [ maxLengths ]
ifFalse: [ maxLengths first: row size ])
do: [ :col :len |
first ifTrue: [
box ifTrue: [ stream nextPutAll: '|' ].
first := false ].
stream
nextPutAll: (justifyEach value: col value: len);
nextPutAll: (box ifTrue: '|' ifFalse: ' ') ].
stream cr ].
box ifTrue: [ printSep value: stream value: maxLengths ] ].
padding := [ :actualLen :expectedLen |
String new: ((expectedLen - actualLen) max: 0) withAll: Character space ].
leftPadded := [ :str :len |
(padding value: str size value: len),
str ].
rightPadded := [ :str :len |
str,
(padding value: str size value: len) ].
centerPadded := [ :str :len |
(padding value: (str size / 2.0) ceiling value: (len / 2.0) ceiling),
str,
(padding value: (str size / 2.0) floor value: (len / 2.0) floor) ].
printRightJustified := [ :stream :rows :box |
printRows
value: stream
value: rows
value: box
value: [ :col :len |
leftPadded value: col value: len ] ].
printLeftJustified := [ :stream :rows :box |
printRows
value: stream
value: rows
value: box
value: [ :col :len |
rightPadded value: col value: len ] ].
printCentered := [ :stream :rows :box |
printRows
value: stream
value: rows
value: box
value: [ :col :len |
centerPadded value: col value: len ] ].
input := 'Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$''dollar''$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column.
'.
output := String streamContents: [ :writeStream |
| inputRows |
inputRows := input lines collect: [ :line | (line trimRight: [ :char | char = $$ ]) splitOn: $$ ].
writeStream
<< 'Left justified:';
cr.
printLeftJustified value: writeStream value: inputRows value: false.
writeStream
cr;
<< 'Right justified:';
cr.
printRightJustified value: writeStream value: inputRows value: false.
writeStream
cr;
<< 'Centered:';
cr.
printCentered value: writeStream value: inputRows value: false.
writeStream
cr;
<< 'Left justified with box:';
cr.
printLeftJustified value: writeStream value: inputRows value: true.
writeStream
cr;
<< 'Right justified with box:';
cr.
printRightJustified value: writeStream value: inputRows value: true.
writeStream
cr;
<< 'Centered with box:';
cr.
printCentered value: writeStream value: inputRows value: true.
].
output traceCr.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment