Vocabulary
wrap

Inputs
elementsa sequence of elements
widtha real


Outputs
arrayan array


Word description
Break the elements into lines such that the total width of each line tries to be less than width while attempting to minimize the raggedness represented by the amount of space at the end of each line. Returns an array of lines.

Definition


:: wrap ( elements width -- array )
elements length integer>fixnum-strict :> #elements elements
[ black>> ] { } map-as :> black elements
[ white>> ] { } map-as :> white #elements 1 + f <array>
:> minima #elements 1 + 0 <array>
:> breaks 0 0 minima set-nth-unsafe minima [| base i |
0 i 1 +
[ dup #elements <= ] [| j |
j 1 - black nth-unsafe + dup :> w j 1 -
white nth-unsafe + w width > [
j 1 - i = [
0 j minima set-nth-unsafe
i j breaks set-nth-unsafe
] when #elements
] [
base j #elements = [ width w - sq + ] unless
:> cost j minima nth-unsafe
[ cost >= ] [ t ] if* [
cost j minima set-nth-unsafe
i j breaks set-nth-unsafe
] when j
] if 1 +
] while 2drop
] each-index #elements
[ dup 0 > ] [
[ breaks nth dup ] keep elements <slice>
[ contents>> ] map
] produce nip reverse ;