Align columns: Difference between revisions

Content added Content deleted
(→‎{{header|Pascal}}: modified Delphi to run with free pascal added seperator | to show columns)
(→‎{{header|Snobol}}: Just track column width as text is read in instead of in a second loop; improve comments.)
Line 7,952: Line 7,952:
=={{header|Snobol}}==
=={{header|Snobol}}==
{{works with|Snobol|4}}
{{works with|Snobol|4}}
<lang snobol>* Since we don't know how many lines or words we'll be reading in,
<lang snobol>* Since we don't know how much text we'll be reading in,
* store them in a table.
* we store the words and field widths in tables
Words = TABLE()
Words = TABLE()
Widths = TABLE()


* Pattern matches text from start of string to the first $ character
* Match text from start of string to the first dollar sign
WordPat = POS(0) BREAK('$') . Word LEN(1) REM . Rest
WordPat = POS(0) BREAK('$') . Word LEN(1) REM . Rest


* We output the results aligned three different ways; these are the
* We output the results aligned three different ways; these are the
* labels for those sections of output:
* labels for those sections of output:
Labels = ARRAY(3)
Labels = ARRAY(3)
Labels<1> = "Left-justified"
Labels<1> = "Left-justified"
Labels<2> = "Right-justified"
Labels<2> = "Right-justified"
Labels<3> = "Centered"
Labels<3> = "Centered"


* There are built-in functions for left- and right- justification,
* There are built-in functions for left- and right- justification,
* but not necessrily one for centering (depending on implementation).
* but not necessarily one for centering (depending on
* So we define one.
* implementation). So we define one.
DEFINE('CPAD(Word,Width)Z,Left') :(CPAD_END)
DEFINE('CPAD(Word,Width)Z,Left') :(END_CPAD)


CPAD Z = SIZE(Word)
CPAD Z = SIZE(Word)
Left = Z + (Width - Z) / 2
Left = Z + (Width - Z) / 2
CPAD = RPAD(LPAD(Word, Left), Width) :(RETURN)
CPAD = RPAD(LPAD(Word, Left), Width) :(RETURN)
END_CPAD
CPAD_END


InLineLoop Line = INPUT :F(DoneReading)
* Read in our text a line at a time and split into words on '$'
LineCount = LineCount + 1
InLineLoop Line = INPUT :F(DoneReading)
Column = 0
LineCount = LineCount + 1
InWordLoop Column = Column + 1
Column = 0
InWordLoop Column = Column + 1
Line WordPat = Rest :S(CheckMax)

Word = Line
Line =
* Separate Line into Word, Line=Rest at first dollar sign
CheckMax GT(Column, MaxColumn) :F(StoreWord)
Line WordPat = Rest :S(CheckMax)

MaxColumn = Column
* If there was no '$', the whole line is the next word
StoreWord Words<LineCount ',' Column> = Word
Word = Line
GT(Size(Line)) :S(InWordLoop)F(InLineLoop)
Line =

* Keep track of the largest number of columns on any line
CheckMax LE(Column, MaxColumn) :S(StoreWord)
MaxColumn = Column

StoreWord Words<LineCount ',' Column> = Word

* And the size of the longest word in each column
GT(SIZE(Word),Widths<Column>) :F(NoNewMaxWidth)
Widths<Column> = SIZE(Word)

* Loop if the line isn't empty yet
NoNewMaxWidth GT(Size(Line)) :S(InWordLoop) F(InLineLoop)
DoneReading
DoneReading


* Now we've read all the words in, find the field widths
* Now we print the results out in the three justification styles
Widths = ARRAY(MaxColumn)
Style = 0
J = 0
StyleLoop Style = Style + 1
GT(Style, 3) :S(END)
FieldLoop J = J + 1
GT(J, MaxColumn) :S(DoneCounting)
OUTPUT =
Widths<J> = 0
OUTPUT = Labels<Style> ':'

I = 0
I = 0
CheckLineLoop I = I + 1
OutLineLoop I = I + 1
GT(I, LineCount) :S(FieldLoop)
L = SIZE(Words<I ',' J>) :F(FieldLoop)
GT(I, LineCount) :S(StyleLoop)
GT(L, Widths<J>) :F(CheckLineLoop)
Widths<J> = L :(CheckLineLoop)
DoneCounting


* Now we print the results out in the three styles
* Build up the output line by fields starting with the null string
Style = 0
Line =
StyleLoop Style = Style + 1
J = 0
OutWordLoop J = J + 1
GT(Style, 3) :S(END)
OUTPUT =
GT(J, MaxColumn) :S(PrintLine)
OUTPUT = Labels<Style> ':'
Word = Words<I ',' J>
GT(SIZE(Word)) :F(PrintLine)


I = 0
* Place the word within the column according to the pass we're on
EQ(Style, 1) :F(NotLeft)
OutLineLoop I = I + 1
* Left-justified
GT(I, LineCount) :S(StyleLoop)
Word = RPAD(Word, Widths<J>) :(AddWord)


* Build up the output line by fields starting with the null string
NotLeft EQ(Style, 2) :F(NotRight)
Line =
* Right-justified
J = 0
Word = LPAD(Word, Widths<J>) :(AddWord)
OutWordLoop J = J + 1
GT(J, MaxColumn) :S(PrintLine)
Word = Words<I ',' J> :F(PrintLine)


* Centered
* Place the word within the column according to the pass we're on
NotRight Word = CPAD(Word, Widths<J>)
EQ(Style, 1) :F(NotLeft)
* Left-justified
Word = RPAD(Word, Widths<J>) :(AddWord)


NotLeft EQ(Style, 2) :F(NotRight)
* Add word to line and loop
* Right-justified
AddWord Line = Line GT(SIZE(Line)) ' '
Word = LPAD(Word, Widths<J>) :(AddWord)
Line = Line Word :(OutWordLoop)


* Centered
NotRight Word = CPAD(Word, Widths<J>)


* Add word to line and loop
* Print the line
AddWord Line = Line Word ' ' :(OutWordLoop)
PrintLine OUTPUT = Line :(OutLineLoop)


END
* Print the line
</lang>
PrintLine OUTPUT = Line :(OutLineLoop)
END</lang>


{{Out}}
{{Out}}