This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

@ -0,0 +1,40 @@
USING: fry io kernel math math.functions math.order sequences
splitting strings ;
IN: rosetta.column-aligner
CONSTANT: example-text "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."
: split-and-pad ( text -- lines )
"\n" split [ "$" split harvest ] map
dup [ length ] [ max ] map-reduce
'[ _ "" pad-tail ] map ;
: column-widths ( columns -- widths )
[ [ length ] [ max ] map-reduce ] map ;
SINGLETONS: +left+ +middle+ +right+ ;
GENERIC: align-string ( str n alignment -- str' )
M: +left+ align-string drop CHAR: space pad-tail ;
M: +right+ align-string drop CHAR: space pad-head ;
M: +middle+ align-string
drop
over length - 2 /
[ floor CHAR: space <string> ]
[ ceiling CHAR: space <string> ] bi surround ;
: align-columns ( columns alignment -- columns' )
[ dup column-widths ] dip '[
[ _ align-string ] curry map
] 2map ;
: print-aligned ( text alignment -- )
[ split-and-pad flip ] dip align-columns flip
[ [ write " " write ] each nl ] each ;

View file

@ -0,0 +1,14 @@
def alignColumns = { align, rawText ->
def lines = rawText.tokenize('\n')
def words = lines.collect { it.tokenize(/\$/) }
def maxLineWords = words.collect {it.size()}.max()
words = words.collect { line -> line + [''] * (maxLineWords - line.size()) }
def columnWidths = words.transpose().collect{ column -> column.collect { it.size() }.max() }
def justify = [ Right : { width, string -> string.padLeft(width) },
Left : { width, string -> string.padRight(width) },
Center : { width, string -> string.center(width) } ]
def padAll = { pad, colWidths, lineWords -> [colWidths, lineWords].transpose().collect { pad(it) + ' ' } }
words.each { padAll(justify[align], columnWidths, it).each { print it }; println() }
}

View file

@ -0,0 +1,12 @@
def rawTextInput = '''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.'''
['Left', 'Center', 'Right'].each { align ->
println "${align} Justified:"
alignColumns(align, rawTextInput)
println()
}

View file

@ -0,0 +1,27 @@
CHARACTER Fnam = "\HicEst\Rosetta\Align columns.txt"
OPEN(FIle=Fnam, Format="12$", LENgth=rows)
! call the DLG function in MatrixExplorer mode:
DLG(Edit=Fnam, Format='12A10') ! left adjusted, 12 columns, 10 spaces each
! or the standard way:
CALL Align( "LLLLLLLLLLL ", Fnam, rows) ! left align
CALL Align( "CCCCCCCCCCC ", Fnam, rows) ! center align
CALL Align( "RRRRRRRRRRR ", Fnam, rows) ! right align
END
SUBROUTINE Align(picture, filename, rows)
CHARACTER picture, filename
CHARACTER out*400, txt*20
W = LEN(picture)
DO i = 1, rows
out = " "
DO j = 0, 100
txt = filename(i, j+1, *9) ! on error branch to label 9
WRITE(Text=out(j*W+1 : ), Format=picture) txt
ENDDO
9 CONTINUE
WRITE() out
ENDDO
END

View file

@ -0,0 +1,30 @@
global width
procedure main(args)
lines := []
width := 0
format := left
match("left"|"right"|"center", format <- !args)
every put(lines,prepare(!&input))
display(lines, proc(format,3))
end
procedure prepare(lines)
line := []
lines ? {
while (not pos(0)) & (field := tab(upto('$')|0)) do {
put(line, field)
width <:= *field
move(1)
}
}
return line
end
procedure display(lines, format)
width +:= 1
every line := !lines do {
every writes(format(!line, width))
write()
}
end

View file

@ -0,0 +1,18 @@
'LEFT CENTER RIGHT'=: i.3 NB. justification constants
NB.* alignCols v Format delimited text in justified columns
NB. y: text to format
NB. rows marked by last character in text
NB. columns marked by $
NB. optional x: justification. Default is LEFT
NB. result: text table
alignCols=: verb define
LEFT alignCols y NB. default
:
global=. dyad def'9!:x y'each
oldbox=. 6 16 global '';'' NB. save settings
7 17 global (11#' ');,~x NB. apply new settings
result=. _2{:\ ": <;._2 @:,&'$';._2 y NB. parse & format text
7 17 global oldbox NB. restore settings
result
)

View file

@ -0,0 +1,24 @@
text=: noun define
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.
)
alignCols text NB. default justification
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.
CENTER alignCols text NB. specify desired justification as left argument
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.

View file

@ -0,0 +1,78 @@
mainwin 140 32
CRLF$ =chr$( 13)
maxlen =0
read y
Dim txt$( y)
For i =1 To y
Read i$
print i$
if right$( i$, 1) <>"$" then i$ =i$ +"$"
txt$( i) =i$
x =max( CountDollars( txt$( i)), x)
Next i
print x
Dim matrix$( x, y)
Print CRLF$; " ---- Left ----"
For yy =1 To y
For xx =1 To x
matrix$( xx, yy) =word$( txt$( yy), xx, "$")
print matrix$( xx, yy), "|";
maxlen =max( maxlen, Len( matrix$( xx, yy)))
Next xx
print ""
Next yy
Print CRLF$; " ---- Right ----"
For yy =1 To y
For xx =1 To x
Print right$( " " +matrix$( xx, yy), maxlen +1); "|";
' will truncate column words longer than 20. Change to use maxlen....
Next xx
Print ""
Next yy
Print CRLF$ +" ---- Center ----"
For yy =1 to y
For xx =1 to x
wordLen =Len( matrix$( xx, yy))
padNeeded =maxlen -wordLen +4
LeftSpaces =padNeeded /2
if LeftSpaces =int( LeftSpaces) then
RightSpaces =LeftSpaces
else
RightSpaces =LeftSpaces -1
end if
Print space$( LeftSpaces); matrix$( xx, yy); space$( RightSpaces); "|";
Next xx
Print ""
Next yy
wait
Data 6
Data "Given$a$text$file$of$many$lines,$where$fields$within$a$line$"
Data "are$delineated$by$a$single$'dollar'$character,$write$a$program"
Data "that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$"
Data "column$are$separated$by$at$least$one$space."
Data "Further,$allow$for$each$word$in$a$column$to$be$either$left$"
Data "justified,$right$justified,$or$center$justified$within$its$column."
function CountDollars( src$)
c =0
for j =1 to len( src$)
if mid$( src$, j, 1) ="$" then c =c +1
next j
CountDollars =c
end function
end

View file

@ -0,0 +1,57 @@
MCSKIP "WITH" NL
"" Align columns - assumes macros on input stream 1, data on stream 2
MCPVAR 102
"" Set P102 to alignment required:
"" 1 = centre
"" 2 = left
"" 3 = right
MCSET P102 = 1
MCSKIP MT,<>
MCINS %.
MCSKIP SL WITH *
"" Assume no more than 100 columns - P101 used for max number of fields
"" Set P variables 1-101 to 0
MCDEF ZEROPS WITHS NL AS <MCSET T1=1
%L1.MCSET PT1=0
MCSET T1=T1+1
MCGO L1 UNLESS T1 EN 102
>
ZEROPS
"" First pass - macro to accumulate max columns, and max widths
MCDEF SL N1 OPT $ N1 OR $ WITHS NL OR SPACE WITHS NL OR NL ALL
AS <MCGO L3 UNLESS T1 GR P101
MCSET P101=T1
%L3.MCSET T2=1
%L1.MCGO L0 IF T2 GR T1
MCSET T3=MCLENG(%WBT2.)
MCGO L2 UNLESS T3 GR PT2
MCSET PT2=T3
%L2.MCSET T2=T2+1
MCGO L1
>
MCSET S1=1
*MCSET S10=2
*MCSET S1=0
MCSET S4=1
""MCNOTE Max field is %P101.
""MCDEF REP NL AS <MCSET T1=1
""%L1.%PT1. MCSET T1=T1+1
""MCGO L1 UNLESS T1 GR P101
"">
""REP
MCDEF SL N1 OPT $ N1 OR $ WITHS NL OR SPACE WITHS NL OR NL ALL
AS <MCSET T2=1
%L5.MCGO L6 IF T2 GR T1
MCGO LP102
%L1.MCSET T3=%%%PT2.-MCLENG(%WBT2.)./2.
MCGO L7 IF T3 EN 0
MCSUB(< >,1,T3)%L7.%WBT2.""
MCSUB(< >,1,PT2-T3-MCLENG(%WBT2.)+1)MCGO L4
%L2.MCSUB(%WBT2.< >,1,PT2)MCGO L4
%L3.MCSUB(< >%WBT2.,1-PT2,0)""
%L4. MCSET T2=T2+1
MCGO L5
%L6.
>
MCSET S1=1
*MCSET S10=102

View file

@ -0,0 +1,53 @@
columns(how) ; how = "Left", "Center" or "Right"
New col,half,ii,max,spaces,word
Set ii=0
Set ii=ii+1,line(ii)="Given$a$text$file$of$many$lines,$where$fields$within$a$line$"
Set ii=ii+1,line(ii)="are$delineated$by$a$single$'dollar'$character,$write$a$program"
Set ii=ii+1,line(ii)="that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$"
Set ii=ii+1,line(ii)="column$are$separated$by$at$least$one$space."
Set ii=ii+1,line(ii)="Further,$allow$for$each$word$in$a$column$to$be$either$left$"
Set ii=ii+1,line(ii)="justified,$right$justified,$or$center$justified$within$its$column."
Set ii="" For Set ii=$Order(line(ii)) Quit:ii="" Do
. For col=1:1:$Length(line(ii),"$") Do
. . Set max=$Length($Piece(line(ii),"$",col))
. . Set:max>$Get(max(col)) max(col)=max
. . Quit
. Quit
Set ii="" For Set ii=$Order(line(ii)) Quit:ii="" Do
. Write ! For col=1:1:$Length(line(ii),"$") Do:$Get(max(col))
. . Set word=$Piece(line(ii),"$",col)
. . Set spaces=$Justify("",max(col)-$Length(word))
. . If how="Left" Write word,spaces," " Quit
. . If how="Right" Write spaces,word," " Quit
. . Set half=$Length(spaces)\2
. . Write $Extract(spaces,1,half),word,$Extract(spaces,half+1,$Length(spaces))," "
. . Quit
. Quit
Write !
Quit
Do columns("Left")
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.
Do columns("Center")
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.
Do columns("Right")
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.

View file

@ -0,0 +1,7 @@
txt :=
"Given$a$text$file$of$many$lines,$where$fields$within$a$line$\n"
"are$delineated$by$a$single$'dollar'$character,$write$a$program\n"
"that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$\n"
"column$are$separated$by$at$least$one$space.\n"
"Further,$allow$for$each$word$in$a$column$to$be$either$left$\n"
"justified,$right$justified,$or$center$justified$within$its$column.\n":

View file

@ -0,0 +1,24 @@
AlignColumns := proc( txt, align :: { "left", "right", "centre" } := "centre" )
uses StringTools;
# Get a list of lists of fields
local A := map( Split, Split( txt ), "$" );
# Calculate the column width
local width := 1 + max( map( L -> max( map( length, L ) ), A ) );
# Add spacing according to the requested type of alignment
if align = "left" then
local J := map( line -> map( PadRight, line, width ), A )
elif align = "right" then
J := map( line -> map( PadLeft, line, width ), A )
else
J := map( line -> map( Center, line, width ), A )
end if;
# Join up the fields in each line.
J := map( cat@op, J );
# Re-assemble the lines into a single string.
Join( J, "\n" )
end proc:

View file

@ -0,0 +1,28 @@
> printf( "%s\n", AlignColumns( txt ) ):
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.
> printf( "%s\n", AlignColumns( txt, "center" ) ): # same as above
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.
> printf( "%s\n", AlignColumns( txt, "left" ) ):
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.
> printf( "%s\n", AlignColumns( txt, "right" ) ):
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.

View file

@ -0,0 +1 @@
TableForm[StringSplit[StringSplit[a,"\n"],"$"],TableAlignments -> Center]