Word wrap

From Rosetta Code
Revision as of 00:25, 16 August 2013 by rosettacode>Alansam (Add NetRexx implementation)
Task
Word wrap
You are encouraged to solve this task according to the task description, using any language you may know.

Even today, with proportional fonts and complex layouts, there are still cases where you need to wrap text at a specified column. The basic task is to wrap a paragraph of text in a simple way in your language. If there is a way to do this that is built-in, trivial, or provided in a standard library, show that. Otherwise implement the minimum length greedy algorithm from Wikipedia.

Show your routine working on a sample of text at two different wrap columns.

Extra credit! Wrap text using a more sophisticated algorithm such as the Knuth and Plass TeX algorithm. If your language provides this, you get easy extra credit, but you must reference documentation indicating that the algorithm is something better than a simple minimimum length algorithm.

If you have both basic and extra credit solutions, show an example where the two algorithms give different results.

Ada

The specification of a class Word_Wrap.Basic in a package Word_Wrap: <lang Ada>generic

  with procedure Put_Line(Line: String);

package Word_Wrap is

  type Basic(Length_Of_Output_Line: Positive) is tagged private;
  procedure Push_Word(State: in out Basic; Word: String);
  procedure New_Paragraph(State: in out Basic);
  procedure Finish(State: in out Basic);

private

  type Basic(Length_Of_Output_Line: Positive) is tagged record
     Line: String(1 .. Length_Of_Output_Line);
     Size: Natural := 0; -- Line(1 .. Size) is relevant
     Top_Of_Paragraph: Boolean := True;
  end record;

end Word_Wrap;</lang>

The implementation of that package:

<lang Ada>package body Word_Wrap is

  procedure Push_Word(State: in out Basic; Word: String) is
  begin
     if Word'Length + State.Size >= State.Length_Of_Output_Line then
        Put_Line(State.Line(1 .. State.Size));
        State.Line(1 .. Word'Length) := Word; -- may raise CE if Word too long
        State.Size := Word'Length;
     elsif State.Size > 0 then
        State.Line(State.Size+1 .. State.Size+1+Word'Length) := ' ' & Word;
        State.Size := State.Size + 1 + Word'Length;
     else
        State.Line(1 .. Word'Length) := Word;
        State.Size := Word'Length;
     end if;
     State.Top_Of_Paragraph := False;
  end Push_Word;
  procedure New_Paragraph(State: in out Basic) is
  begin
     Finish(State);
     if not State.Top_Of_Paragraph then
        Put_Line("");
        State.Top_Of_Paragraph := True;
     end if;
  end New_Paragraph;
  procedure Finish(State: in out Basic) is
  begin
     if State.Size > 0 then
        Put_Line(State.Line(1 .. State.Size));
        State.Size := 0;
     end if;
  end Finish;

end Word_Wrap;</lang>

Finally, the main program:

<lang Ada>with Ada.Text_IO, Word_Wrap, Ada.Strings.Unbounded, Ada.Command_Line;

procedure Wrap is

  use  Ada.Strings.Unbounded;
  Line: Unbounded_String;
  Word: Unbounded_String;
  function "+"(S: String) return Unbounded_String renames To_Unbounded_String;
  function "-"(U: Unbounded_String) return String renames To_String;
  package IO renames Ada.Text_IO;
  procedure Split(S: Unbounded_String; First, Rest: out Unbounded_String) is
     function Skip_Leading_Spaces(S: String) return String is
     begin
        if S="" then return "";
        elsif S(S'First) = ' ' then return S(S'First+1 .. S'Last);
        else return S;
        end if;
     end Skip_Leading_Spaces;
     Str: String := Skip_Leading_Spaces(-S);
     I: Positive := Str'First;
     J: Natural;
  begin
     -- read nonspaces for First output param
     J := I-1;
     while J < Str'Last and then Str(J+1) /= ' ' loop
        J := J + 1;
     end loop;
     First := + Str(I .. J);
     -- write output param Rest
     Rest  := + Skip_Leading_Spaces(Str(J+1 .. Str'Last));
  end Split;
  procedure Print(S: String) is
  begin
     IO.Put_Line(S);
  end Print;
  package WW is new Word_Wrap(Print);
  Wrapper: WW.Basic(Integer'Value(Ada.Command_Line.Argument(1)));

begin

  while not IO.End_Of_File loop
     Line := +IO.Get_Line;
     if Line = +"" then
        Wrapper.New_Paragraph;
        Line := +IO.Get_Line;
     end if;
     while Line /= +"" loop
        Split(Line, First => Word, Rest => Line);
        Wrapper.Push_Word(-Word);
     end loop;
  end loop;
  Wrapper.Finish;

end Wrap;</lang>

Output, set to 72 lines (with input picked by cut-and-paste from the task description):

Even today, with proportional fonts and complex layouts, there are still
cases where you need to wrap text at a specified column. The basic task
is to wrap a paragraph of text in a simple way in your language. If
there is a way to do this that is built-in, trivial, or provided in a
standard library, show that. Otherwise implement the minimum length
greedy algorithm from Wikipedia.

Show your routine working on a sample of text at two different wrap
columns.

Extra credit! Wrap text using a more sophisticated algorithm such as the
Knuth and Plass TeX algorithm. If your language provides this, you get
easy extra credit, but you must reference documentation indicating that
the algorithm is something better than a simple minimimum length
algorithm.

If you have both basic and extra credit solutions, show an example where
the two algorithms give different results.

Note that this solution properly deals with multi-paragraph inputs. For more sophisticated algorithms (the extra credit), one could derive a class Word_Wrap.<something> from Word_Wrap.Basic.

AWK

Basic word wrap.

<lang awk>function wordwrap_paragraph(p) {

 if ( length(p) < 1 ) return
 
 split(p, words)
 spaceLeft = lineWidth
 line = words[1]
 delete words[1]
 for (i = 1; i <= length(words); i++) {
   word = words[i]
   if ( (length(word) + 1) > spaceLeft ) {
     print line
     line = word
     spaceLeft = lineWidth -  length(word)
   } else {
     spaceLeft -= length(word) + 1
     line = line " " word
   }
 }
 print line

}

BEGIN {

 lineWidth = width
 par = ""

}

/^[ \t]*$/ {

 wordwrap_paragraph(par)
 par = ""

}

!/^[ \t]*$/ {

 par = par " " $0

}

END {

 wordwrap_paragraph(par)

}</lang>

To test it,

awk -f wordwrap.awk -v width=80 < text.txt

Bracmat

<lang bracmat>( str

   $ ( "In olden times when wishing still helped one, there lived a king "
       "whose daughters were all beautiful, but the youngest was so beautiful "
       "that the sun itself, which has seen so much, was astonished whenever "
       "it shone in her face.  Close by the king's castle lay a great dark "
       "forest, and under an old lime tree in the forest was a well, and when "
       "the day was very warm, the king's child went out into the forest and "
       "sat down by the side of the cool fountain, and when she was bored she "
       "took a golden ball, and threw it up on high and caught it, and this "
       "ball was her favorite plaything."
     )
 : ?Text

& ( wrap

 =   txt length line output q
   .   !arg:(?txt.?length)
     & :?output
     &   whl
       ' ( @( str$!txt
            :   ?line
                (" " %?lastword [?q " " ?txt&!q:~<!length)
            )
         & !lastword " " !txt:?txt
         & !output !line \n:?output
         )
     & str$(!output !txt)
 )

& out$(str$("72 columns:\n" wrap$(!Text.72))) & out$(str$("\n80 columns:\n" wrap$(!Text.80))) );</lang> Output:

72 columns:
In olden times when wishing still helped one, there lived a king whose
daughters were all beautiful, but the youngest was so beautiful that
the sun itself, which has seen so much, was astonished whenever it
shone in her face.  Close by the king's castle lay a great dark forest,
and under an old lime tree in the forest was a well, and when the day
was very warm, the king's child went out into the forest and sat down
by the side of the cool fountain, and when she was bored she took a
golden ball, and threw it up on high and caught it, and this ball was
plaything.

80 columns:
In olden times when wishing still helped one, there lived a king whose
daughters were all beautiful, but the youngest was so beautiful that the sun
itself, which has seen so much, was astonished whenever it shone in her face.
 Close by the king's castle lay a great dark forest, and under an old lime tree
in the forest was a well, and when the day was very warm, the king's child went
out into the forest and sat down by the side of the cool fountain, and when she
was bored she took a golden ball, and threw it up on high and caught it, and
plaything.

C

<lang c>#include <stdio.h>

  1. include <stdlib.h>
  2. include <string.h>
  3. include <ctype.h>

/* nonsensical hyphens to make greedy wrapping method look bad */ const char *string = "In olden times when wishing still helped one, there lived a king " "whose daughters were all beautiful, but the youngest was so beautiful " "that the sun itself, which has seen so much, was astonished whenever " "it shone-in-her-face. Close-by-the-king's castle lay a great dark " "forest, and under an old lime-tree in the forest was a well, and when " "the day was very warm, the king's child went out into the forest and " "sat down by the side of the cool-fountain, and when she was bored she " "took a golden ball, and threw it up on high and caught it, and this " "ball was her favorite plaything.";

/* Each but the last of wrapped lines comes with some penalty as the square of the diff between line length and desired line length. If the line is longer than desired length, the penalty is multiplied by 100. This pretty much prohibits the wrapping routine from going over right margin. If is ok to exceed the margin just a little, something like 20 or 40 will do.

Knuth uses a per-paragraph penalty for line-breaking in TeX, which is-- unlike what I have here--probably bug-free.

  • /
  1. define PENALTY_LONG 100
  2. define PENALTY_SHORT 1

typedef struct word_t { const char *s; int len; } *word;

word make_word_list(const char *s, int *n) { int max_n = 0; word words = 0;

*n = 0; while (1) { while (*s && isspace(*s)) s++; if (!*s) break;

if (*n >= max_n) { if (!(max_n *= 2)) max_n = 2; words = realloc(words, max_n * sizeof(*words)); } words[*n].s = s; while (*s && !isspace(*s)) s++; words[*n].len = s - words[*n].s; (*n) ++; }

return words; }

int greedy_wrap(word words, int count, int cols, int *breaks) { int score = 0, line, i, j, d;

i = j = line = 0; while (1) { if (i == count) { breaks[j++] = i; break; }

if (!line) { line = words[i++].len; continue; }

if (line + words[i].len < cols) { line += words[i++].len + 1; continue; }

breaks[j++] = i; if (i < count) { d = cols - line; if (d > 0) score += PENALTY_SHORT * d * d; else if (d < 0) score += PENALTY_LONG * d * d; }

line = 0; } breaks[j++] = 0;

return score; }

/* tries to make right margin more even; pretty sure there's an off-by-one bug here somewhere */ int balanced_wrap(word words, int count, int cols, int *breaks) { int *best = malloc(sizeof(int) * (count + 1));

/* do a greedy wrap to have some baseline score to work with, else we'll end up with O(2^N) behavior */ int best_score = greedy_wrap(words, count, cols, breaks);

void test_wrap(int line_no, int start, int score) { int line = 0, current_score = -1, d;

while (start <= count) { if (line) line ++; line += words[start++].len; d = cols - line; if (start < count || d < 0) { if (d > 0) current_score = score + PENALTY_SHORT * d * d; else current_score = score + PENALTY_LONG * d * d; } else { current_score = score; }

if (current_score >= best_score) { if (d <= 0) return; continue; }

best[line_no] = start; test_wrap(line_no + 1, start, current_score); } if (current_score >= 0 && current_score < best_score) { best_score = current_score; memcpy(breaks, best, sizeof(int) * (line_no)); } } test_wrap(0, 0, 0); free(best);

return best_score; }

void show_wrap(word list, int count, int *breaks) { int i, j; for (i = j = 0; i < count && breaks[i]; i++) { while (j < breaks[i]) { printf("%.*s", list[j].len, list[j].s); if (j < breaks[i] - 1) putchar(' '); j++; } if (breaks[i]) putchar('\n'); } }

int main(void) { int len, score, cols; word list = make_word_list(string, &len); int *breaks = malloc(sizeof(int) * (len + 1));

cols = 80; score = greedy_wrap(list, len, cols, breaks); printf("\n== greedy wrap at %d (score %d) ==\n\n", cols, score); show_wrap(list, len, breaks);

score = balanced_wrap(list, len, cols, breaks); printf("\n== balanced wrap at %d (score %d) ==\n\n", cols, score); show_wrap(list, len, breaks);


cols = 32; score = greedy_wrap(list, len, cols, breaks); printf("\n== greedy wrap at %d (score %d) ==\n\n", cols, score); show_wrap(list, len, breaks);

score = balanced_wrap(list, len, cols, breaks); printf("\n== balanced wrap at %d (score %d) ==\n\n", cols, score); show_wrap(list, len, breaks);

return 0; }</lang>

C++

Basic task.

Translation of: Go

<lang cpp>#include <iostream>

  1. include <sstream>
  2. include <string>

const char *text = {

   "In olden times when wishing still helped one, there lived a king "
   "whose daughters were all beautiful, but the youngest was so beautiful "
   "that the sun itself, which has seen so much, was astonished whenever "
   "it shone in her face.  Close by the king's castle lay a great dark "
   "forest, and under an old lime tree in the forest was a well, and when "
   "the day was very warm, the king's child went out into the forest and "
   "sat down by the side of the cool fountain, and when she was bored she "
   "took a golden ball, and threw it up on high and caught it, and this "
   "ball was her favorite plaything."

};

std::string wrap(const char *text, size_t line_length = 72) {

   std::istringstream words(text);
   std::ostringstream wrapped;
   std::string word;
   if (words >> word) {
       wrapped << word;
       size_t space_left = line_length - word.length();
       while (words >> word) {
           if (space_left < word.length() + 1) {
               wrapped << '\n' << word;
               space_left = line_length - word.length();
           } else {
               wrapped << ' ' << word;
               space_left -= word.length() + 1;
           }
       }
   }
   return wrapped.str();

}

int main() {

   std::cout << "Wrapped at 72:\n" << wrap(text) << "\n\n";
   std::cout << "Wrapped at 80:\n" << wrap(text, 80) << "\n";

}</lang>

Output:
Wrapped at 72:
In olden times when wishing still helped one, there lived a king whose
daughters were all beautiful, but the youngest was so beautiful that the
sun itself, which has seen so much, was astonished whenever it shone in
her face. Close by the king's castle lay a great dark forest, and under
an old lime tree in the forest was a well, and when the day was very
warm, the king's child went out into the forest and sat down by the side
of the cool fountain, and when she was bored she took a golden ball, and
threw it up on high and caught it, and this ball was her favorite
plaything.

Wrapped at 80:
In olden times when wishing still helped one, there lived a king whose daughters
were all beautiful, but the youngest was so beautiful that the sun itself, which
has seen so much, was astonished whenever it shone in her face. Close by the
king's castle lay a great dark forest, and under an old lime tree in the forest
was a well, and when the day was very warm, the king's child went out into the
forest and sat down by the side of the cool fountain, and when she was bored she
took a golden ball, and threw it up on high and caught it, and this ball was her
favorite plaything.

C#

Greedy algorithm: <lang csharp>namespace RosettaCode.WordWrap {

   using System;
   using System.Collections.Generic;
   internal static class Program
   {
       private const string LoremIpsum = @"

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas varius sapien vel purus hendrerit vehicula. Integer hendrerit viverra turpis, ac sagittis arcu pharetra id. Sed dapibus enim non dui posuere sit amet rhoncus tellus consectetur. Proin blandit lacus vitae nibh tincidunt cursus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam tincidunt purus at tortor tincidunt et aliquam dui gravida. Nulla consectetur sem vel felis vulputate et imperdiet orci pharetra. Nam vel tortor nisi. Sed eget porta tortor. Aliquam suscipit lacus vel odio faucibus tempor. Sed ipsum est, condimentum eget eleifend ac, ultricies non dui. Integer tempus, nunc sed venenatis feugiat, augue orci pellentesque risus, nec pretium lacus enim eu nibh.";

       private static void Main()
       {
           foreach (var lineWidth in new[] { 72, 80 })
           {
               Console.WriteLine(new string('-', lineWidth));
               Console.WriteLine(Wrap(LoremIpsum, lineWidth));
           }
       }
       private static string Wrap(string text, int lineWidth)
       {
           return string.Join(string.Empty,
                              Wrap(
                                  text.Split(new char[0],
                                             StringSplitOptions
                                                 .RemoveEmptyEntries),
                                  lineWidth));
       }
       private static IEnumerable<string> Wrap(IEnumerable<string> words,
                                               int lineWidth)
       {
           var currentWidth = 0;
           foreach (var word in words)
           {
               if (currentWidth != 0)
               {
                   if (currentWidth + word.Length < lineWidth)
                   {
                       currentWidth++;
                       yield return " ";
                   }
                   else
                   {
                       currentWidth = 0;
                       yield return Environment.NewLine;
                   }
               }
               currentWidth += word.Length;
               yield return word;
           }
       }
   }

}</lang> Output:

------------------------------------------------------------------------
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas varius
sapien vel purus hendrerit vehicula. Integer hendrerit viverra turpis,
ac sagittis arcu pharetra id. Sed dapibus enim non dui posuere sit amet
rhoncus tellus consectetur. Proin blandit lacus vitae nibh tincidunt
cursus. Cum sociis natoque penatibus et magnis dis parturient montes,
nascetur ridiculus mus. Nam tincidunt purus at tortor tincidunt et
aliquam dui gravida. Nulla consectetur sem vel felis vulputate et
imperdiet orci pharetra. Nam vel tortor nisi. Sed eget porta tortor.
Aliquam suscipit lacus vel odio faucibus tempor. Sed ipsum est,
condimentum eget eleifend ac, ultricies non dui. Integer tempus, nunc
sed venenatis feugiat, augue orci pellentesque risus, nec pretium lacus
enim eu nibh.
--------------------------------------------------------------------------------
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas varius sapien
vel purus hendrerit vehicula. Integer hendrerit viverra turpis, ac sagittis arcu
pharetra id. Sed dapibus enim non dui posuere sit amet rhoncus tellus
consectetur. Proin blandit lacus vitae nibh tincidunt cursus. Cum sociis natoque
penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam tincidunt
purus at tortor tincidunt et aliquam dui gravida. Nulla consectetur sem vel
felis vulputate et imperdiet orci pharetra. Nam vel tortor nisi. Sed eget porta
tortor. Aliquam suscipit lacus vel odio faucibus tempor. Sed ipsum est,
condimentum eget eleifend ac, ultricies non dui. Integer tempus, nunc sed
venenatis feugiat, augue orci pellentesque risus, nec pretium lacus enim eu
nibh.

Clojure

<lang Clojure>;; Wrap line naive version (defn wrap-line [size text]

 (loop [left size line [] lines []
        words (clojure.string/split text #"\s+")]
   (if-let [word (first words)]
     (let [wlen (count word)
           spacing (if (== left size) "" " ")
           alen (+ (count spacing) wlen)]
       (if (<= alen left)
         (recur (- left alen) (conj line spacing word) lines (next words))
         (recur (- size wlen) [word] (conj lines (apply str line)) (next words))))
     (when (seq line)
       (conj lines (apply str line))))))</lang>

<lang Clojure>;; Wrap line base on regular expression (defn wrap-line [size text]

 (re-seq (re-pattern (str ".{0," size "}\\s"))
         (clojure.string/replace text #"\n" " ")))</lang>

Usage example : <lang Clojure>(def text "In olden times when wishing still helped one, there lived a king whose daughters were all beautiful, but the youngest was so beautiful that the sun itself, which has seen so much, was astonished whenever it shone in her face. Close by the king's castle lay a great dark forest, and under an old lime-tree in the forest was a well, and when the day was very warm, the king's child went out into the forest and sat down by the side of the cool fountain, and when she was bored she took a golden ball, and threw it up on high and caught it, and this ball was her favorite plaything.")

(doseq [line (wrap-line 72 text)]

 (println line))</lang>

Output :

In olden times when wishing still helped one, there lived a king whose
daughters were all beautiful, but the youngest was so beautiful that the
sun itself, which has seen so much, was astonished whenever it shone in
her face. Close by the king's castle lay a great dark forest, and under
an old lime-tree in the forest was a well, and when the day was very
warm, the king's child went out into the forest and sat down by the side
of the cool fountain, and when she was bored she took a golden ball, and
threw it up on high and caught it, and this ball was her favorite
plaything.

D

Standard Version

<lang d>void main() {

   immutable frog =

"In olden times when wishing still helped one, there lived a king whose daughters were all beautiful, but the youngest was so beautiful that the sun itself, which has seen so much, was astonished whenever it shone in her face. Close by the king's castle lay a great dark forest, and under an old lime-tree in the forest was a well, and when the day was very warm, the king's child went out into the forest and sat down by the side of the cool fountain, and when she was bored she took a golden ball, and threw it up on high and caught it, and this ball was her favorite plaything.";

   import std.stdio, std.string;
   foreach (width; [72, 80])
       writefln("Wrapped at %d:\n%s\n", width, frog.wrap(width));

}</lang>

Output:
Wrapped at 72:
In olden times when wishing still helped one, there lived a king whose
daughters were all beautiful, but the youngest was so beautiful that the
sun itself, which has seen so much, was astonished whenever it shone in
her face. Close by the king's castle lay a great dark forest, and under
an old lime-tree in the forest was a well, and when the day was very
warm, the king's child went out into the forest and sat down by the side
of the cool fountain, and when she was bored she took a golden ball, and
threw it up on high and caught it, and this ball was her favorite
plaything.


Wrapped at 80:
In olden times when wishing still helped one, there lived a king whose daughters
were all beautiful, but the youngest was so beautiful that the sun itself, which
has seen so much, was astonished whenever it shone in her face. Close by the
king's castle lay a great dark forest, and under an old lime-tree in the forest
was a well, and when the day was very warm, the king's child went out into the
forest and sat down by the side of the cool fountain, and when she was bored she
took a golden ball, and threw it up on high and caught it, and this ball was her
favorite plaything.

An Implementation

Basic algorithm. The text splitting is lazy.

Translation of: Go

<lang d>import std.algorithm;

string wrap(in string text, in int lineWidth) {

   auto words = text.splitter;
   if (words.empty) return null;
   string wrapped = words.front;
   words.popFront();
   int spaceLeft = lineWidth - wrapped.length;
   foreach (word; words)
       if (word.length + 1 > spaceLeft) {
           wrapped ~= "\n" ~ word;
           spaceLeft = lineWidth - word.length;
       } else {
           wrapped ~= " " ~ word;
           spaceLeft -= 1 + word.length;
       }
   return wrapped;

}

void main() {

   immutable frog =

"In olden times when wishing still helped one, there lived a king whose daughters were all beautiful, but the youngest was so beautiful that the sun itself, which has seen so much, was astonished whenever it shone in her face. Close by the king's castle lay a great dark forest, and under an old lime-tree in the forest was a well, and when the day was very warm, the king's child went out into the forest and sat down by the side of the cool fountain, and when she was bored she took a golden ball, and threw it up on high and caught it, and this ball was her favorite plaything.";

   import std.stdio;
   foreach (width; [72, 80])
       writefln("Wrapped at %d:\n%s\n", width, frog.wrap(width));

}</lang>

Output:
Wrapped at 72:
In olden times when wishing still helped one, there lived a king whose
daughters were all beautiful, but the youngest was so beautiful that the
sun itself, which has seen so much, was astonished whenever it shone in
her face. Close by the king's castle lay a great dark forest, and under
an old lime-tree in the forest was a well, and when the day was very
warm, the king's child went out into the forest and sat down by the side
of the cool fountain, and when she was bored she took a golden ball, and
threw it up on high and caught it, and this ball was her favorite
plaything.

Wrapped at 80:
In olden times when wishing still helped one, there lived a king whose daughters
were all beautiful, but the youngest was so beautiful that the sun itself, which
has seen so much, was astonished whenever it shone in her face. Close by the
king's castle lay a great dark forest, and under an old lime-tree in the forest
was a well, and when the day was very warm, the king's child went out into the
forest and sat down by the side of the cool fountain, and when she was bored she
took a golden ball, and threw it up on high and caught it, and this ball was her
favorite plaything.

Erlang

<lang Erlang> -module( word_wrap ).

-export( [paragraph/2, task/0] ).

paragraph( String, Max_line_length ) -> Lines = lines( string:tokens(String, " "), Max_line_length ), string:join( Lines, "\n" ).

task() -> Paragraph = "Even today, with proportional fonts and complex layouts, there are still cases where you need to wrap text at a specified column. The basic task is to wrap a paragraph of text in a simple way in your language. If there is a way to do this that is built-in, trivial, or provided in a standard library, show that. Otherwise implement the minimum length greedy algorithm from Wikipedia.", io:fwrite( "~s~n~n", [paragraph(Paragraph, 72)] ), io:fwrite( "~s~n~n", [paragraph(Paragraph, 80)] ).


lines( [Word | T], Max_line_length ) -> {Max_line_length, _Length, Last_line, Lines} = lists:foldl( fun lines_assemble/2, {Max_line_length, erlang:length(Word), Word, []}, T ), lists:reverse( [Last_line | Lines] ).

lines_assemble( Word, {Max, Line_length, Line, Acc} ) when erlang:length(Word) + Line_length > Max -> {Max, erlang:length(Word), Word, [Line | Acc]}; lines_assemble( Word, {Max, Line_length, Line, Acc} ) -> {Max, Line_length + 1 + erlang:length(Word), Line ++ " " ++ Word, Acc}. </lang>

Output:
15> word_wrap:task().
Even today, with proportional fonts and complex layouts, there are still
cases where you need to wrap text at a specified column. The basic task
is to wrap a paragraph of text in a simple way in your language. If there
is a way to do this that is built-in, trivial, or provided in a standard
library, show that. Otherwise implement the minimum length greedy
algorithm from Wikipedia.

Even today, with proportional fonts and complex layouts, there are still cases
where you need to wrap text at a specified column. The basic task is to wrap a
paragraph of text in a simple way in your language. If there is a way to do this
that is built-in, trivial, or provided in a standard library, show that.
Otherwise implement the minimum length greedy algorithm from Wikipedia.

F#

Translation of: C#

<lang fsharp>open System

let LoremIpsum = " Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas varius sapien vel purus hendrerit vehicula. Integer hendrerit viverra turpis, ac sagittis arcu pharetra id. Sed dapibus enim non dui posuere sit amet rhoncus tellus consectetur. Proin blandit lacus vitae nibh tincidunt cursus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam tincidunt purus at tortor tincidunt et aliquam dui gravida. Nulla consectetur sem vel felis vulputate et imperdiet orci pharetra. Nam vel tortor nisi. Sed eget porta tortor. Aliquam suscipit lacus vel odio faucibus tempor. Sed ipsum est, condimentum eget eleifend ac, ultricies non dui. Integer tempus, nunc sed venenatis feugiat, augue orci pellentesque risus, nec pretium lacus enim eu nibh."

let Wrap words lineWidth =

   let rec loop words currentWidth = seq {
       match (words : string list) with
       | word :: rest -> 
           let (stuff, pos) =
               if currentWidth > 0 then
                   if currentWidth + word.Length < lineWidth then
                       (" ", (currentWidth + 1))
                   else
                       ("\n", 0)
               else ("", 0)
           yield stuff + word
           yield! loop rest (pos + word.Length)
       | _ -> ()
   }
   loop words 0

[<EntryPoint>] let main argv =

   for n in [72; 80] do
       printfn "%s" (String('-', n))
       let l = Seq.toList (LoremIpsum.Split((null:char[]), StringSplitOptions.RemoveEmptyEntries))
       Wrap l n |> Seq.iter (printf "%s")
       printfn ""
   0</lang>

Output

------------------------------------------------------------------------
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas varius
sapien vel purus hendrerit vehicula. Integer hendrerit viverra turpis,
ac sagittis arcu pharetra id. Sed dapibus enim non dui posuere sit amet
rhoncus tellus consectetur. Proin blandit lacus vitae nibh tincidunt
cursus. Cum sociis natoque penatibus et magnis dis parturient montes,
nascetur ridiculus mus. Nam tincidunt purus at tortor tincidunt et
aliquam dui gravida. Nulla consectetur sem vel felis vulputate et
imperdiet orci pharetra. Nam vel tortor nisi. Sed eget porta tortor.
Aliquam suscipit lacus vel odio faucibus tempor. Sed ipsum est,
condimentum eget eleifend ac, ultricies non dui. Integer tempus, nunc
sed venenatis feugiat, augue orci pellentesque risus, nec pretium lacus
enim eu nibh.
--------------------------------------------------------------------------------
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas varius sapien
vel purus hendrerit vehicula. Integer hendrerit viverra turpis, ac sagittis arcu
pharetra id. Sed dapibus enim non dui posuere sit amet rhoncus tellus
consectetur. Proin blandit lacus vitae nibh tincidunt cursus. Cum sociis natoque
penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam tincidunt
purus at tortor tincidunt et aliquam dui gravida. Nulla consectetur sem vel
felis vulputate et imperdiet orci pharetra. Nam vel tortor nisi. Sed eget porta
tortor. Aliquam suscipit lacus vel odio faucibus tempor. Sed ipsum est,
condimentum eget eleifend ac, ultricies non dui. Integer tempus, nunc sed
venenatis feugiat, augue orci pellentesque risus, nec pretium lacus enim eu
nibh.

Forth

<lang forth>\ wrap text \ usage: gforth wrap.f in.txt 72

0. argc @ 1- arg >number 2drop drop constant maxLine

.wrapped ( buf len -- )
 begin
   dup maxLine >
 while
   over maxLine
   begin 1- 2dup + c@ bl = until
   dup 1+ >r
   begin 1- 2dup + c@ bl <> until
   1+ type cr
   r> /string
 repeat type cr ;
strip-nl ( buf len -- )
 bounds do
   i c@ 10 = if bl i c! then
 loop ;

argc @ 2 - arg slurp-file 2dup strip-nl .wrapped bye</lang>

Go

Basic task, no extra credit. <lang go>package main

import (

   "fmt"
   "strings"

)

func wrap(text string, lineWidth int) (wrapped string) {

   words := strings.Fields(text)
   if len(words) == 0 {
       return
   }
   wrapped = words[0]
   spaceLeft := lineWidth - len(wrapped)
   for _, word := range words[1:] {
       if len(word)+1 > spaceLeft {
           wrapped += "\n" + word
           spaceLeft = lineWidth - len(word)
       } else {
           wrapped += " " + word
           spaceLeft -= 1 + len(word)
       }
   }
   return

}

var frog = ` In olden times when wishing still helped one, there lived a king whose daughters were all beautiful, but the youngest was so beautiful that the sun itself, which has seen so much, was astonished whenever it shone in her face. Close by the king's castle lay a great dark forest, and under an old lime-tree in the forest was a well, and when the day was very warm, the king's child went out into the forest and sat down by the side of the cool fountain, and when she was bored she took a golden ball, and threw it up on high and caught it, and this ball was her favorite plaything.`

func main() {

   fmt.Println("wrapped at 80:")
   fmt.Println(wrap(frog, 80))
   fmt.Println("wrapped at 72:")
   fmt.Println(wrap(frog, 72))

}</lang>

Output:
wrapped at 80:
In olden times when wishing still helped one, there lived a king whose daughters
were all beautiful, but the youngest was so beautiful that the sun itself, which
has seen so much, was astonished whenever it shone in her face. Close by the
king's castle lay a great dark forest, and under an old lime-tree in the forest
was a well, and when the day was very warm, the king's child went out into the
forest and sat down by the side of the cool fountain, and when she was bored she
took a golden ball, and threw it up on high and caught it, and this ball was her
favorite plaything.
wrapped at 72:
In olden times when wishing still helped one, there lived a king whose
daughters were all beautiful, but the youngest was so beautiful that the
sun itself, which has seen so much, was astonished whenever it shone in
her face. Close by the king's castle lay a great dark forest, and under
an old lime-tree in the forest was a well, and when the day was very
warm, the king's child went out into the forest and sat down by the side
of the cool fountain, and when she was bored she took a golden ball, and
threw it up on high and caught it, and this ball was her favorite
plaything.


Haskell

Greedy wrapping: <lang haskell>ss = "In olden times when wishing still helped one, there lived a king"

  ++"whose daughters were all beautiful, but the youngest was so beautiful"
  ++"that the sun itself, which has seen so much, was astonished whenever"
  ++"it shone in her face.  Close by the king's castle lay a great dark"
  ++"forest, and under an old lime-tree in the forest was a well, and when"
  ++"the day was very warm, the king's child went out into the forest and"
  ++"sat down by the side of the cool fountain, and when she was bored she"
  ++"took a golden ball, and threw it up on high and caught it, and this"
  ++"ball was her favorite plaything."

wordwrap maxlen = (wrap_ 0) . words where wrap_ _ [] = "\n" wrap_ pos (w:ws) -- at line start: put down the word no matter what | pos == 0 = w ++ wrap_ (pos + lw) ws | pos + lw + 1 > maxlen = '\n':wrap_ 0 (w:ws) | otherwise = " " ++ w ++ wrap_ (pos + lw + 1) ws where lw = length w

main = do putStr $ wordwrap 72 ss putStr "\n" putStr $ wordwrap 32 ss</lang>

J

Solution:<lang j>ww =: 75&$: : wrap

 wrap    =: (] turn edges) ,&' '
   turn  =:  LF"_`]`[}
   edges =: (_1 + ] #~ 1 ,~ 2 >/\ |) [: +/\ #;.2</lang>

Example:<lang j> GA =: 'Four score and seven years ago, our forefathers brought forth upon this continent a new nation, dedicated to the proposition that all men were created equal.'

  ww GA  NB.  Wrap at 75 chars by default

Four score and seven years ago, our forefathers brought forth upon this continent a new nation, dedicated to the proposition that all men were created equal.

  20 ww GA  NB.  Specify different length

Four score and seven years ago, our forefathers brought forth upon this continent a new nation, dedicated to the proposition that all men were created equal.</lang>

Java

<lang java> package rosettacode;

import java.util.StringTokenizer;

public class WordWrap { int defaultLineWidth=80; int defaultSpaceWidth=1; void minNumLinesWrap(String text) { minNumLinesWrap(text,defaultLineWidth); } void minNumLinesWrap(String text,int LineWidth) { StringTokenizer st=new StringTokenizer(text); int SpaceLeft=LineWidth; int SpaceWidth=defaultSpaceWidth; while(st.hasMoreTokens()) { String word=st.nextToken(); if((word.length()+SpaceWidth)>SpaceLeft) { System.out.print("\n"+word+" "); SpaceLeft=LineWidth-word.length(); } else { System.out.print(word+" "); SpaceLeft-=(word.length()+SpaceWidth); } } } public static void main(String[] args) { WordWrap now=new WordWrap(); String wodehouse="Old Mr MacFarland (_said Henry_) started the place fifteen years ago. He was a widower with one son and what you might call half a daughter. That's to say, he had adopted her. Katie was her name, and she was the child of a dead friend of his. The son's name was Andy. A little freckled nipper he was when I first knew him--one of those silent kids that don't say much and have as much obstinacy in them as if they were mules. Many's the time, in them days, I've clumped him on the head and told him to do something; and he didn't run yelling to his pa, same as most kids would have done, but just said nothing and went on not doing whatever it was I had told him to do. That was the sort of disposition Andy had, and it grew on him. Why, when he came back from Oxford College the time the old man sent for him--what I'm going to tell you about soon--he had a jaw on him like the ram of a battleship. Katie was the kid for my money. I liked Katie. We all liked Katie."; System.out.println("DEFAULT:"); now.minNumLinesWrap(wodehouse); System.out.println("\n\nLINEWIDTH=120"); now.minNumLinesWrap(wodehouse,120); }

}

</lang>

Output:

DEFAULT:
Old Mr MacFarland (_said Henry_) started the place fifteen years ago. He was a 
widower with one son and what you might call half a daughter. That's to say, he 
had adopted her. Katie was her name, and she was the child of a dead friend of 
his. The son's name was Andy. A little freckled nipper he was when I first knew 
him--one of those silent kids that don't say much and have as much obstinacy in 
them as if they were mules. Many's the time, in them days, I've clumped him on 
the head and told him to do something; and he didn't run yelling to his pa, same 
as most kids would have done, but just said nothing and went on not doing 
whatever it was I had told him to do. That was the sort of disposition Andy had, 
and it grew on him. Why, when he came back from Oxford College the time the old 
man sent for him--what I'm going to tell you about soon--he had a jaw on him 
like the ram of a battleship. Katie was the kid for my money. I liked Katie. We 
all liked Katie. 

LINEWIDTH=120
Old Mr MacFarland (_said Henry_) started the place fifteen years ago. He was a widower with one son and what you might 
call half a daughter. That's to say, he had adopted her. Katie was her name, and she was the child of a dead friend of 
his. The son's name was Andy. A little freckled nipper he was when I first knew him--one of those silent kids that don't 
say much and have as much obstinacy in them as if they were mules. Many's the time, in them days, I've clumped him on 
the head and told him to do something; and he didn't run yelling to his pa, same as most kids would have done, but just 
said nothing and went on not doing whatever it was I had told him to do. That was the sort of disposition Andy had, and 
it grew on him. Why, when he came back from Oxford College the time the old man sent for him--what I'm going to tell you 
about soon--he had a jaw on him like the ram of a battleship. Katie was the kid for my money. I liked Katie. We all 
liked Katie. 

NetRexx

<lang NetRexx>/* NetRexx */ options replace format comments java crossref symbols

runSample(arg) return

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /*

  @see http://en.wikipedia.org/wiki/Word_wrap#Minimum_length
  SpaceLeft := LineWidth
  for each Word in Text
      if (Width(Word) + SpaceWidth) > SpaceLeft
          insert line break before Word in Text
          SpaceLeft := LineWidth - Width(Word)
      else
          SpaceLeft := SpaceLeft - (Width(Word) + SpaceWidth)
*/

method wordWrap(text, lineWidth = 80) public static

 if lineWidth > 0 then do
   NL = '\n'
   SP = ' '
   wrapped = 
   spaceWidth = SP.length()
   spaceLeft = lineWidth
   loop w_ = 1 to text.words()
     nextWord = text.word(w_)
     if (nextWord.length() + spaceWidth) > spaceLeft then do
       wrapped = wrapped || NL || nextWord
       spaceLeft = lineWidth - nextWord.length()
       end
     else do
       wrapped = wrapped || SP || nextWord
       spaceLeft = spaceLeft - (nextWord.length() + spaceWidth)
       end
     end w_
   end
 else do
   wrapped = text
   end
 
 return wrapped.strip() -- clean w/s from front & back

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ method runSample(arg) public static

 parse arg lineLen .
 if lineLen  =  then lineLen = 80
 text = getText()
 wrappedLines = wordWrap(text, lineLen)
 say 'Wrapping text at' lineLen 'characters'
 say ('....+....|'.copies((lineLen + 9) % 10)).left(lineLen)
 say wrappedLines
 
 return

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ method getText() public static

 -- ....+....|....+....|....+....|....+....|....+....|....+....|
 speech01 = -
   'She should have died hereafter;' -
   'There would have been a time for such a word.' -
   'Tomorrow, and tomorrow, and tomorrow,' -
   'Creeps in this petty pace from day to day,' -
   'To the last syllable of recorded time;' -
   'And all our yesterdays have lighted fools' -
   'The way to dusty death. Out, out, brief candle!' -
   'Lifes but a walking shadow, a poor player' -
   'That struts and frets his hour upon the stage' -
   'And then is heard no more. It is a tale' -
   'Told by an idiot, full of sound and fury' -
   'Signifying nothing.' -
    -
   '—-Macbeth (Act 5, Scene 5, lines 17-28)' -
   
 return speech01

</lang>

Output:
Wrapping text at 64 characters
....+....|....+....|....+....|....+....|....+....|....+....|....
She should have died hereafter; There would have been a time
for such a word. Tomorrow, and tomorrow, and tomorrow, Creeps in
this petty pace from day to day, To the last syllable of
recorded time; And all our yesterdays have lighted fools The way
to dusty death. Out, out, brief candle! Life's but a walking
shadow, a poor player That struts and frets his hour upon the
stage And then is heard no more. It is a tale Told by an idiot,
full of sound and fury Signifying nothing. —-Macbeth (Act 5,
Scene 5, lines 17-28)

Wrapping text at 132 characters
....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....|..
She should have died hereafter; There would have been a time for such a word. Tomorrow, and tomorrow, and tomorrow, Creeps in this
petty pace from day to day, To the last syllable of recorded time; And all our yesterdays have lighted fools The way to dusty death.
Out, out, brief candle! Life's but a walking shadow, a poor player That struts and frets his hour upon the stage And then is heard
no more. It is a tale Told by an idiot, full of sound and fury Signifying nothing. —-Macbeth (Act 5, Scene 5, lines 17-28)

OCaml

<lang ocaml>#load "str.cma"

let txt = "In olden times when wishing still helped one, there lived a king whose daughters were all beautiful, but the youngest was so beautiful that the sun itself, which has seen so much, was astonished whenever it shone in her face. Close by the king's castle lay a great dark forest, and under an old lime-tree in the forest was a well, and when the day was very warm, the king's child went out into the forest and sat down by the side of the cool fountain, and when she was bored she took a golden ball, and threw it up on high and caught it, and this ball was her favorite plaything."

let () =

 let line_width = int_of_string Sys.argv.(1) in
 let words = Str.split (Str.regexp "[ \n]+") txt in
 let buf = Buffer.create 10 in
 let _ =
   List.fold_left (fun (width, sep) word ->
     let wlen = String.length word in
     let len = width + wlen + 1 in
     if len > line_width then
     begin
       Buffer.add_char buf '\n';
       Buffer.add_string buf word;
       (wlen, " ")
     end else begin
       Buffer.add_string buf sep;
       Buffer.add_string buf word;
       (len, " ")
     end
   ) (0, "") words
 in
 print_endline (Buffer.contents buf)</lang>

Testing:

$ ocaml word_wrap.ml 80 | wc -L
79
$ ocaml word_wrap.ml 72 | wc -L
72
$ ocaml word_wrap.ml 50 | wc -L
50

PARI/GP

<lang parigp>wrap(s,len)={

 my(t="",cur);
 s=Vec(s);
 for(i=1,#s,
   if(s[i]==" ",
     if(cur>#t,
       print1(" "t);
       cur-=#t+1
     ,
       print1("\n"t);
       cur=len-#t
     );
     t=""
   ,
     t=concat(t,s[i])
   )
 );
 if(cur>#t,
   print1(" "t)
 ,
   print1("\n"t)
 )

}; King="And so let freedom ring from the prodigious hilltops of New Hampshire; let freedom ring from the mighty mountains of New York; let freedom ring from the heightening Alleghenies of Pennsylvania; let freedom ring from the snow-capped Rockies of Colorado; let freedom ring from the curvaceous slopes of California. But not only that: let freedom ring from Stone Mountain of Georgia; let freedom ring from Lookout Mountain of Tennessee; let freedom ring from every hill and molehill of Mississippi. From every mountainside, let freedom ring."; wrap(King, 75) wrap(King, 50)</lang>

Output:

And so let freedom ring from the prodigious hilltops of New Hampshire; let
freedom ring from the mighty mountains of New York; let freedom ring from
the heightening Alleghenies of Pennsylvania; let freedom ring from the
snow-capped Rockies of Colorado; let freedom ring from the curvaceous
slopes of California. But not only that: let freedom ring from Stone
Mountain of Georgia; let freedom ring from Lookout Mountain of Tennessee;
let freedom ring from every hill and molehill of Mississippi. From every
mountainside, let freedom ring.

And so let freedom ring from the prodigious
hilltops of New Hampshire; let freedom ring from
the mighty mountains of New York; let freedom ring
from the heightening Alleghenies of Pennsylvania;
let freedom ring from the snow-capped Rockies of
Colorado; let freedom ring from the curvaceous
slopes of California. But not only that: let
freedom ring from Stone Mountain of Georgia; let
freedom ring from Lookout Mountain of Tennessee;
let freedom ring from every hill and molehill of
Mississippi. From every mountainside, let freedom
ring.

Perl

Regex. Also showing degraded behavior on very long words: <lang perl>my $s = "In olden times when wishing still helped one, there lived a king whose daughters were all beautiful, but the youngest was so beautiful that the sun itself, which has seen so much, was astonished whenever it shone in her face. Close-by-the-king's-castle-lay-a-great-dark forest, and under an old lime-tree in the forest was a well, and when the day was very warm, the king's child went out into the forest and sat down by the side of the cool fountain, and when she was bored she took a golden ball, and threw it up on high and caught it, and this ball was her favorite plaything.";

$s =~ s/\b\s+/ /g; $s =~ s/\s*$/\n\n/;

my $_ = $s; s/\s*(.{1,66})\s/$1\n/g, print;

$_ = $s; s/\s*(.{1,25})\s/$1\n/g, print;</lang>

Perl 6

<lang perl6>my $s = "In olden times when wishing still helped one, there lived a king whose daughters were all beautiful, but the youngest was so beautiful that the sun itself, which has seen so much, was astonished whenever it shone in her face. Close-by-the-king's-castle-lay-a-great-dark forest, and under an old lime-tree in the forest was a well, and when the day was very warm, the king's child went out into the forest and sat down by the side of the cool fountain, and when she was bored she took a golden ball, and threw it up on high and caught it, and this ball was her favorite plaything.";

$s ~~ s:g/»\s+/ /; $s ~~ s/\s*$/\n\n/;

say $s.subst(/ \s* (. ** 1..66) \s /, -> $/ { "$0\n" }, :g); say $s.subst(/ \s* (. ** 1..25) \s /, -> $/ { "$0\n" }, :g);</lang>

PicoLisp

'wrap' is a built-in. <lang PicoLisp>: (prinl (wrap 12 (chop "The quick brown fox jumps over the lazy dog"))) The quick brown fox jumps over the lazy dog -> "The quick^Jbrown fox^Jjumps over^Jthe lazy dog"</lang>

Python

>>> import textwrap
>>> help(textwrap.fill)
Help on function fill in module textwrap:

fill(text, width=70, **kwargs)
    Fill a single paragraph of text, returning a new string.
    
    Reformat the single paragraph in 'text' to fit in lines of no more
    than 'width' columns, and return a new string containing the entire
    wrapped paragraph.  As with wrap(), tabs are expanded and other
    whitespace characters converted to space.  See TextWrapper class for
    available keyword args to customize wrapping behaviour.

>>> txt = '''\
Reformat the single paragraph in 'text' to fit in lines of no more
than 'width' columns, and return a new string containing the entire
wrapped paragraph.  As with wrap(), tabs are expanded and other
whitespace characters converted to space.  See TextWrapper class for
available keyword args to customize wrapping behaviour.'''
>>> print(textwrap.fill(txt, width=75))
Reformat the single paragraph in 'text' to fit in lines of no more than
'width' columns, and return a new string containing the entire wrapped
paragraph.  As with wrap(), tabs are expanded and other whitespace
characters converted to space.  See TextWrapper class for available keyword
args to customize wrapping behaviour.
>>> print(textwrap.fill(txt, width=45))
Reformat the single paragraph in 'text' to
fit in lines of no more than 'width' columns,
and return a new string containing the entire
wrapped paragraph.  As with wrap(), tabs are
expanded and other whitespace characters
converted to space.  See TextWrapper class
for available keyword args to customize
wrapping behaviour.
>>> print(textwrap.fill(txt, width=85))
Reformat the single paragraph in 'text' to fit in lines of no more than 'width'
columns, and return a new string containing the entire wrapped paragraph.  As with
wrap(), tabs are expanded and other whitespace characters converted to space.  See
TextWrapper class for available keyword args to customize wrapping behaviour.
>>> 

Racket

Using a library function: <lang Racket>

  1. lang at-exp racket

(require scribble/text/wrap) (define text

 @(λ xs (regexp-replace* #rx" *\n *" (string-append* xs) " ")){
   In olden times when wishing still helped one, there lived a king whose
   daughters were all beautiful, but the youngest was so beautiful that the
   sun itself, which has seen so much, was astonished whenever it shone in her
   face.  Close by the king's castle lay a great dark forest, and under an old
   lime-tree in the forest was a well, and when the day was very warm, the
   king's child went out into the forest and sat down by the side of the cool
   fountain, and when she was bored she took a golden ball, and threw it up on
   high and caught it, and this ball was her favorite plaything.})

(for-each displayln (wrap-line text 60)) </lang>

Explicit (and simple) implementation: <lang racket>

  1. lang racket

(define (wrap words width)

 (define (maybe-cons xs xss)
   (if (empty? xs) xss (cons xs xss)))  
 (match/values
   (for/fold ([lines '()] [line '()] [left width]) ([w words])
     (define n (string-length w))
     (cond
       [(> n width) ; word longer than line => line on its own
        (values (cons (list w) (maybe-cons line lines)) '() width)]
       [(> n left)  ; not enough space left => new line
        (values (cons line lines) (list w) (- width n 1))]
       [else
        (values lines (cons w line) (- left n 1))]))
   [(lines line _)
    (apply string-append
           (for/list ([line (reverse (cons line lines))])
             (string-join line #:after-last "\n")))]))
Usage

(wrap (string-split text) 70) </lang>

REXX

The input for this program is in a file (named LAWS.TXT).
The default width of the output is ½ of the current terminal width (normally, this would be the window's width), or
if the terminal width (or window's width) is indeterminable, then 40 is used.
No hyphenation (or de-hyphenation) is attempted.
Words longer than the width of the output are acceptable and are shown, a simple change could be made to issue a notification. <lang rexx>/*REXX program justifies (by words) a string of words ───► screen. */ arg justify width . /*───────────JUSTIFY─────────────*/

                                      /*Center:       ◄centered►       */
                                      /*  Both:   ◄──both margins──►   */
                                      /* Right:  ────────►right margin */
                                      /*  Left:   left margin◄──────── */
                                      /*═════pick one of the above.════*/

just=left(justify,1) /*only use first capital letter. */

if width== then width=linesize()%2 /*It's null? Then pick a default*/ if width==0 then width=40 /*Not determinable? Then use 40.*/

txt="Diplomacy is the art of saying 'Nice Doggy' until",

   "you can find a rock.             ─── Will Rodgers"

$= /*this is where the money is. */

 do k=1 for words(txt); x=word(txt,k) /*parse 'til we exhaust the TXT. */
 _=$ x                                /*append it to da money and see. */
 if length(_)►width then call tell    /*word(s) exceeded the width?    */
 $=_                                  /*the new words are OK so far.   */
 end

call tell /*handle any residual words. */ exit /*stick a fork in it, we're done.*/ /*──────────────────────────────────TELL subroutine─────────────────────*/ tell: if $== then return /*first word may be too long. */

            select
            when just=='B' then $=justify($,width)     /*◄────both────►*/
            when just=='C' then $= center($,width)     /*  ◄centered►  */
            when just=='R' then $=  right($,width)     /*──────► right */
            otherwise           $=  strip($)           /*left ◄────────*/
            end   /*select*/
     say $                            /*show and tell, or write──►file?*/
     _=x                              /*handle any word overflow.      */
     return                           /*go back and keep truckin'.     */</lang>

The input file:

     ────────── Computer programming laws ──────────
 The Primal Scenario  -or-  Basic Datum of Experience:
    ∙ Systems in general work poorly or not at all.
    ∙ Nothing complicated works.
    ∙ Complicated systems seldom exceed 5% efficiency.
    ∙ There is always a fly in the ointment.
 The Fundamental Theorem:
    ∙ New systems generate new problems.
 Occam's Razor:
    ∙ Systems should not be unnecessarily multiplied.
 The Law of Conservation of Energy:
    ∙ The total amount of energy in the universe is constant.
    ∙ Systems operate by redistributing energy into different forms and into accumulations of different sizes.
 Laws of Growth:
    ∙ Systems tend to grow, and as they grow, they encroach.
 The Big-Bang Theorem of Systems-Cosmology:
    ∙ Systems tend to expand to fill the known universe.
 Parkinson's Extended Law:
    ∙ The system itself tends to expand at 5-6% per annum.
 The Generalized Uncertainty Principle:
    ∙ Systems display antics.
    ∙ Complicated systems produce unexpected outcomes.
    ∙ The total behavior of large systems cannot be predicted.
 The Non-Addivity Theorem of Systems-Behavior -or- Climax Design Theorem:
    ∙ A large system, produced by expanding the dimensions of a smaller system, does not behave like the smaller system.
 LeChateliers's Principle:
    ∙ Complex systems tend to oppose their own proper function.
    ∙ Systems get in the way.
    ∙ The system always kicks back.
    ∙ Positive feedback is dangerous.
 Functionary's Falsity:
    ∙ People in systems do not do what the system says they are doing.
    ∙ The function performed by a system is not operationally identical to the function of the same name performed by a man.
    ∙ A function performed by a larger system is not operationally identical to the function of the same name performed by a smaller system.
 The Fundamental Law of Administrative Workings:
    ∙ Things are what they are reported to be.
    ∙ The real world is whatever is reported to the system.
    ∙ If it isn't official; it didn't happen.
    ∙ If it's made in Detriot, it must be an automobile.
    ∙ A system is no better than its sensory organs.
    ∙ To those within a system, the outside reality tends to pale and disappear.
    ∙ Systems attract systems-people.
    ∙ For every human system, there is a type of person adapted to thrive on it or in it.
    ∙ The bigger the system, the narrower and more specialized the interface with individuals.
 Administrator's Anxiety:
    ∙ Pushing on the systems doesn't help.  It just makes things worse.
    ∙ A complex system cannot be "made" to work.  It either works or it doesn't.
    ∙ A simple system, designed from scratch, sometimes works.
    ∙ A simple system may or may not work.
    ∙ Some complex systems actually work.
    ∙ If a system is working, leave it alone.
    ∙ A complex system that works is invariably found to have evolved from a simple system that works.
    ∙ A complex system designed from scratch never works and cannot be patched up to make it work.  You have to start over, beginning with a working simple system.
    ∙ Programs never run the first time.
    ∙ Complex programs never run.
    ∙ Anything worth doing once will probably have to be done twice.
 The Functional indeterminancy Theorem:
    ∙ In complex systems, malfunction and even total nonfunction may not be detectable for long periods, if ever.
 The Kantian Hypothesis  -or-  Know-Nothing Theorem:
    ∙ Large complex systems are beyond human capacity to evaluate.
 The Newtonian Lay of Systems-Inertia:
    ∙ A system that performs a certain way will continue to operate in that way regardless of the need of of changed conditions.
    ∙ A system continues to do its thing, regardless of need.
    ∙ Systems develop goals of their own the instant they come into being.
    ∙ Intrasystem goals come first.
 Failure-Mode Theorems:
    ∙ Complex systems usually operate in failure mode.
    ∙ A complex system can fail in a infinite number of ways.
    ∙ If anything can go wrong, it will.
    ∙ The mode of failure of a complex system cannot ordinarily be predicted from its structure.
    ∙ The crucial variables are discovered by accident.
    ∙ The larger the system, the greater the probability of unexpected failure.
    ∙ "Success" or "function" in any system may be failure in the larger or smaller systems to which the system is connected.
    ∙ In setting up a new system, tread softly.  You may be disturbing another system that is actually working.
 The Fail-Safe Theorem:
    ∙ When a fail-safe system fails, it fails by failing to fail safe.
    ∙ Complex systems tend to produce complex responses (not solutions) to problems.
    ∙ Great advances are not produced by systems designed to produce great advances.
    ∙ Loose systems last longer and work better.
    ∙ Efficient systems are dangerous to themselves and to others.
 The Vector Theory of Systems:
    ∙ Systems run better when designed to run downhill.
    ∙ Systems aligned with human motivational vectors will sometimes work.  Systems opposing such vectors work poorly or not at all.
 Advanced Systems Theories:
    ∙ Everything is a system.
    ∙ Everything is a part of a larger system.
    ∙ The universe is infinitely systematized, both upward [larger systems] and downward [smaller systems].
    ∙ All systems are infinitely complex.  (The illusion of simplicity comes from focusing attention on one or a few variables.)
    ∙ Parameters are variables travelling under an assumed name.

Output when specifying: , 155

────────── Computer programming laws ────────── The Primal Scenario -or- Basic Datum of Experience: ∙ Systems in general work poorly or not at all. ∙
Nothing complicated works. ∙ Complicated systems seldom exceed 5% efficiency. ∙ There is always a fly in the ointment. The Fundamental Theorem: ∙ New
systems generate new problems. Occam's Razor: ∙ Systems should not be unnecessarily multiplied. The Law of Conservation of Energy: ∙ The total amount of
energy in the universe is constant. ∙ Systems operate by redistributing energy into different forms and into accumulations of different sizes. Laws of
Growth: ∙ Systems tend to grow, and as they grow, they encroach. The Big-Bang Theorem of Systems-Cosmology: ∙ Systems tend to expand to fill the known
universe. Parkinson's Extended Law: ∙ The system itself tends to expand at 5-6% per annum. The Generalized Uncertainty Principle: ∙ Systems display antics.
∙ Complicated systems produce unexpected outcomes. ∙ The total behavior of large systems cannot be predicted. The Non-Addivity Theorem of Systems-Behavior
-or- Climax Design Theorem: ∙ A large system, produced by expanding the dimensions of a smaller system, does not behave like the smaller system.
LeChateliers's Principle: ∙ Complex systems tend to oppose their own proper function. ∙ Systems get in the way. ∙ The system always kicks back. ∙ Positive
feedback is dangerous. Functionary's Falsity: ∙ People in systems do not do what the system says they are doing. ∙ The function performed by a system is
not operationally identical to the function of the same name performed by a man. ∙ A function performed by a larger system is not operationally identical
to the function of the same name performed by a smaller system. The Fundamental Law of Administrative Workings: ∙ Things are what they are reported to be.
∙ The real world is whatever is reported to the system. ∙ If it isn't official; it didn't happen. ∙ If it's made in Detriot, it must be an automobile. ∙ A
system is no better than its sensory organs. ∙ To those within a system, the outside reality tends to pale and disappear. ∙ Systems attract systems-people.
∙ For every human system, there is a type of person adapted to thrive on it or in it. ∙ The bigger the system, the narrower and more specialized the
interface with individuals. Administrator's Anxiety: ∙ Pushing on the systems doesn't help. It just makes things worse. ∙ A complex system cannot be "made"
to work. It either works or it doesn't. ∙ A simple system, designed from scratch, sometimes works. ∙ A simple system may or may not work. ∙ Some complex
systems actually work. ∙ If a system is working, leave it alone. ∙ A complex system that works is invariably found to have evolved from a simple system
that works. ∙ A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over, beginning with a working
simple system. ∙ Programs never run the first time. ∙ Complex programs never run. ∙ Anything worth doing once will probably have to be done twice. The
Functional indeterminancy Theorem: ∙ In complex systems, malfunction and even total nonfunction may not be detectable for long periods, if ever. The
Kantian Hypothesis -or- Know-Nothing Theorem: ∙ Large complex systems are beyond human capacity to evaluate. The Newtonian Lay of Systems-Inertia: ∙ A
system that performs a certain way will continue to operate in that way regardless of the need of of changed conditions. ∙ A system continues to do its
thing, regardless of need. ∙ Systems develop goals of their own the instant they come into being. ∙ Intrasystem goals come first. Failure-Mode Theorems: ∙
Complex systems usually operate in failure mode. ∙ A complex system can fail in a infinite number of ways. ∙ If anything can go wrong, it will. ∙ The mode
of failure of a complex system cannot ordinarily be predicted from its structure. ∙ The crucial variables are discovered by accident. ∙ The larger the
system, the greater the probability of unexpected failure. ∙ "Success" or "function" in any system may be failure in the larger or smaller systems to which
the system is connected. ∙ In setting up a new system, tread softly. You may be disturbing another system that is actually working. The Fail-Safe Theorem:
∙ When a fail-safe system fails, it fails by failing to fail safe. ∙ Complex systems tend to produce complex responses (not solutions) to problems. ∙ Great
advances are not produced by systems designed to produce great advances. ∙ Loose systems last longer and work better. ∙ Efficient systems are dangerous to
themselves and to others. The Vector Theory of Systems: ∙ Systems run better when designed to run downhill. ∙ Systems aligned with human motivational
vectors will sometimes work. Systems opposing such vectors work poorly or not at all. Advanced Systems Theories: ∙ Everything is a system. ∙ Everything is
a part of a larger system. ∙ The universe is infinitely systematized, both upward [larger systems] and downward [smaller systems]. ∙ All systems are
infinitely complex. (The illusion of simplicity comes from focusing attention on one or a few variables.) ∙ Parameters are variables travelling under an
assumed name.

Output when specifying: , 76

────────── Computer programming laws ────────── The Primal Scenario -or-
Basic Datum of Experience: ∙ Systems in general work poorly or not at all.
∙ Nothing complicated works. ∙ Complicated systems seldom exceed 5%
efficiency. ∙ There is always a fly in the ointment. The Fundamental
Theorem: ∙ New systems generate new problems. Occam's Razor: ∙ Systems
should not be unnecessarily multiplied. The Law of Conservation of Energy:
∙ The total amount of energy in the universe is constant. ∙ Systems operate
by redistributing energy into different forms and into accumulations of
different sizes. Laws of Growth: ∙ Systems tend to grow, and as they grow,
they encroach. The Big-Bang Theorem of Systems-Cosmology: ∙ Systems tend to
expand to fill the known universe. Parkinson's Extended Law: ∙ The system
itself tends to expand at 5-6% per annum. The Generalized Uncertainty
Principle: ∙ Systems display antics. ∙ Complicated systems produce
unexpected outcomes. ∙ The total behavior of large systems cannot be
predicted. The Non-Addivity Theorem of Systems-Behavior -or- Climax Design
Theorem: ∙ A large system, produced by expanding the dimensions of a
smaller system, does not behave like the smaller system. LeChateliers's
Principle: ∙ Complex systems tend to oppose their own proper function. ∙
Systems get in the way. ∙ The system always kicks back. ∙ Positive feedback
is dangerous. Functionary's Falsity: ∙ People in systems do not do what the
system says they are doing. ∙ The function performed by a system is not
operationally identical to the function of the same name performed by a
man. ∙ A function performed by a larger system is not operationally
identical to the function of the same name performed by a smaller system.
The Fundamental Law of Administrative Workings: ∙ Things are what they are
reported to be. ∙ The real world is whatever is reported to the system. ∙
If it isn't official; it didn't happen. ∙ If it's made in Detriot, it must
be an automobile. ∙ A system is no better than its sensory organs. ∙ To
those within a system, the outside reality tends to pale and disappear. ∙
Systems attract systems-people. ∙ For every human system, there is a type
of person adapted to thrive on it or in it. ∙ The bigger the system, the
narrower and more specialized the interface with individuals.
Administrator's Anxiety: ∙ Pushing on the systems doesn't help. It just
makes things worse. ∙ A complex system cannot be "made" to work. It either
works or it doesn't. ∙ A simple system, designed from scratch, sometimes
works. ∙ A simple system may or may not work. ∙ Some complex systems
actually work. ∙ If a system is working, leave it alone. ∙ A complex system
that works is invariably found to have evolved from a simple system that
works. ∙ A complex system designed from scratch never works and cannot be
patched up to make it work. You have to start over, beginning with a
working simple system. ∙ Programs never run the first time. ∙ Complex
programs never run. ∙ Anything worth doing once will probably have to be
done twice. The Functional indeterminancy Theorem: ∙ In complex systems,
malfunction and even total nonfunction may not be detectable for long
periods, if ever. The Kantian Hypothesis -or- Know-Nothing Theorem: ∙ Large
complex systems are beyond human capacity to evaluate. The Newtonian Lay of
Systems-Inertia: ∙ A system that performs a certain way will continue to
operate in that way regardless of the need of of changed conditions. ∙ A
system continues to do its thing, regardless of need. ∙ Systems develop
goals of their own the instant they come into being. ∙ Intrasystem goals
come first. Failure-Mode Theorems: ∙ Complex systems usually operate in
failure mode. ∙ A complex system can fail in a infinite number of ways. ∙
If anything can go wrong, it will. ∙ The mode of failure of a complex
system cannot ordinarily be predicted from its structure. ∙ The crucial
variables are discovered by accident. ∙ The larger the system, the greater
the probability of unexpected failure. ∙ "Success" or "function" in any
system may be failure in the larger or smaller systems to which the system
is connected. ∙ In setting up a new system, tread softly. You may be
disturbing another system that is actually working. The Fail-Safe Theorem:
∙ When a fail-safe system fails, it fails by failing to fail safe. ∙
Complex systems tend to produce complex responses (not solutions) to
problems. ∙ Great advances are not produced by systems designed to produce
great advances. ∙ Loose systems last longer and work better. ∙ Efficient
systems are dangerous to themselves and to others. The Vector Theory of
Systems: ∙ Systems run better when designed to run downhill. ∙ Systems
aligned with human motivational vectors will sometimes work. Systems
opposing such vectors work poorly or not at all. Advanced Systems Theories:
∙ Everything is a system. ∙ Everything is a part of a larger system. ∙ The
universe is infinitely systematized, both upward [larger systems] and
downward [smaller systems]. ∙ All systems are infinitely complex. (The
illusion of simplicity comes from focusing attention on one or a few
variables.) ∙ Parameters are variables travelling under an assumed name.

Output [justified] when specifying: j 70

────────── Computer programming  laws  ──────────  The Primal Scenario
-or- Basic Datum of Experience:  ∙  Systems  in general work poorly or
not at all. ∙ Nothing  complicated works. ∙ Complicated systems seldom
exceed 5% efficiency. ∙ There  is  always  a  fly in the ointment. The
Fundamental Theorem:  ∙  New  systems  generate  new problems. Occam's
Razor: ∙ Systems should  not  be  unnecessarily multiplied. The Law of
Conservation of Energy: ∙ The  total  amount of energy in the universe
is constant. ∙ Systems operate by redistributing energy into different
forms and into accumulations  of  different  sizes.  Laws of Growth: ∙
Systems tend to grow, and  as  they  grow, they encroach. The Big-Bang
Theorem of Systems-Cosmology: ∙  Systems  tend  to  expand to fill the
known universe. Parkinson's Extended Law: ∙ The system itself tends to
expand at 5-6%  per  annum.  The  Generalized Uncertainty Principle: ∙
Systems  display  antics.  ∙  Complicated  systems  produce unexpected
outcomes. ∙ The total behavior  of  large systems cannot be predicted.
The  Non-Addivity  Theorem  of  Systems-Behavior  -or-  Climax  Design
Theorem: ∙ A large system,  produced  by expanding the dimensions of a
smaller  system,   does   not   behave   like   the   smaller  system.
LeChateliers's Principle: ∙ Complex  systems  tend to oppose their own
proper function. ∙ Systems get in  the  way. ∙ The system always kicks
back. ∙  Positive  feedback  is  dangerous.  Functionary's  Falsity: ∙
People in systems do not do what the system says they are doing. ∙ The
function performed by a system  is  not operationally identical to the
function of the same name performed  by  a man. ∙ A function performed
by a larger system is  not  operationally identical to the function of
the same name performed by  a  smaller  system. The Fundamental Law of
Administrative Workings: ∙ Things are what  they are reported to be. ∙
The real world is whatever is  reported  to  the system. ∙ If it isn't
official; it didn't happen. ∙ If  it's  made in Detriot, it must be an
automobile. ∙ A system  is  no  better  than  its sensory organs. ∙ To
those  within  a  system,  the  outside  reality  tends  to  pale  and
disappear. ∙ Systems attract systems-people. ∙ For every human system,
there is a type of person  adapted  to  thrive  on  it or in it. ∙ The
bigger the system,  the  narrower  and  more specialized the interface
with individuals. Administrator's  Anxiety:  ∙  Pushing on the systems
doesn't help. It just makes things worse. ∙ A complex system cannot be
"made" to work. It  either  works  or  it  doesn't. ∙ A simple system,
designed from scratch, sometimes works.  ∙  A simple system may or may
not work. ∙ Some  complex  systems  actually  work.  ∙  If a system is
working, leave it alone. ∙  A  complex system that works is invariably
found to have evolved from  a  simple  system  that works. ∙ A complex
system designed from scratch never  works  and cannot be patched up to
make it work. You have to  start over, beginning with a working simple
system. ∙ Programs never run the  first time. ∙ Complex programs never
run. ∙ Anything worth doing once  will probably have to be done twice.
The  Functional  indeterminancy   Theorem:   ∙   In  complex  systems,
malfunction and even total nonfunction  may not be detectable for long
periods, if ever. The Kantian  Hypothesis -or- Know-Nothing Theorem: ∙
Large complex  systems  are  beyond  human  capacity  to evaluate. The
Newtonian Lay of Systems-Inertia: ∙  A  system that performs a certain
way will continue to operate in that  way regardless of the need of of
changed conditions. ∙ A system  continues  to do its thing, regardless
of need. ∙ Systems develop  goals  of  their own the instant they come
into being. ∙ Intrasystem  goals  come first. Failure-Mode Theorems: ∙
Complex systems usually operate  in  failure  mode. ∙ A complex system
can fail in a infinite number of  ways. ∙ If anything can go wrong, it
will. ∙ The mode of failure  of  a complex system cannot ordinarily be
predicted from its structure.  ∙  The crucial variables are discovered
by accident. ∙ The larger  the  system, the greater the probability of
unexpected failure. ∙ "Success"  or  "function"  in  any system may be
failure in the  larger  or  smaller  systems  to  which  the system is
connected. ∙ In setting  up  a  new  system,  tread softly. You may be
disturbing another  system  that  is  actually  working. The Fail-Safe
Theorem: ∙ When a fail-safe system  fails, it fails by failing to fail
safe.  ∙  Complex  systems  tend  to  produce  complex  responses (not
solutions) to problems. ∙ Great  advances  are not produced by systems
designed to produce great  advances.  ∙  Loose systems last longer and
work better. ∙ Efficient  systems  are  dangerous to themselves and to
others. The  Vector  Theory  of  Systems:  ∙  Systems  run better when
designed to run downhill.  ∙  Systems  aligned with human motivational
vectors will sometimes work. Systems opposing such vectors work poorly
or not at all. Advanced Systems  Theories: ∙ Everything is a system. ∙
Everything is a part of a  larger system. ∙ The universe is infinitely
systematized,  both  upward  [larger  systems]  and  downward [smaller
systems]. ∙  All  systems  are  infinitely  complex.  (The illusion of
simplicity comes from focusing attention on one or a few variables.) ∙
Parameters  are   variables   travelling   under   an   assumed  name.

Ruby

<lang ruby>class String

 def wrap(width)
   txt = gsub(/\s+/, " ")
   para = []
   i = 0
   while i < txt.length 
     j = i + width
     j -= 1 while txt[j] != " "
     para << txt[i .. j-1]
     i = j + 1
   end
   para.join("\n")
 end

end

text = <<END In olden times when wishing still helped one, there lived a king whose daughters were all beautiful, but the youngest was so beautiful that the sun itself, which has seen so much, was astonished whenever it shone in her face. Close by the king's castle lay a great dark forest, and under an old lime-tree in the forest was a well, and when the day was very warm, the king's child went out into the forest and sat down by the side of the cool fountain, and when she was bored she took a golden ball, and threw it up on high and caught it, and this ball was her favorite plaything. END

[72,80].each do |w|

 puts "." * w
 puts text.wrap(w)

end</lang>

outputs

........................................................................
In olden times when wishing still helped one, there lived a king whose
daughters were all beautiful, but the youngest was so beautiful that the
sun itself, which has seen so much, was astonished whenever it shone in
her face. Close by the king's castle lay a great dark forest, and under
an old lime-tree in the forest was a well, and when the day was very
warm, the king's child went out into the forest and sat down by the side
of the cool fountain, and when she was bored she took a golden ball, and
threw it up on high and caught it, and this ball was her favorite
plaything.
................................................................................
In olden times when wishing still helped one, there lived a king whose daughters
were all beautiful, but the youngest was so beautiful that the sun itself, which
has seen so much, was astonished whenever it shone in her face. Close by the
king's castle lay a great dark forest, and under an old lime-tree in the forest
was a well, and when the day was very warm, the king's child went out into the
forest and sat down by the side of the cool fountain, and when she was bored she
took a golden ball, and threw it up on high and caught it, and this ball was her
favorite plaything.

Run BASIC

Word Wrap style for different browsers. This automatically adjusts the text if the browser window is stretched in any direction <lang runbasic>doc$ = "In olden times when wishing still helped one, there lived a king ";_ "whose daughters were all beautiful, but the youngest was so beautiful ";_ "that the sun itself, which has seen so much, was astonished whenever ";_ "it shone in her face."

wrap$ = " style='white-space: pre-wrap;white-space: -moz-pre-wrap;white-space: -pre-wrap;";_

               "white-space: -o-pre-wrap;word-wrap: break-word'"
html "<tr" + wrap$ +" valign=top>" html "
" + doc$ + "" + doc$ + "
"</lang>

output will adjust as you stretch the browser and maintain a 60 to 40 ratio of the width of the screen.

---------- at 60%-----------------------                         | -------- at 40%----------------------
In olden times when wishing still helped one, there lived a king | In olden times when wishing still helped 
whose daughters were all beautiful, but the youngest was so      | one, there lived a king whose daughters 
beautiful that the sun itself, which has seen so much, was       | were all beautiful, but the youngest was 
astonished whenever it shone in her face.	                 | so beautiful that the sun itself, which 
								 | has seen so much, was astonished whenever
								 | it shone in her face.

Without Browser <lang runbasic>doc$ = "In olden times when wishing still helped one, there lived a king whose daughters were all beautiful, but the youngest was so beautiful that the sun itself, which has seen so much, was astonished whenever it shone in her face. Close by the king's castle lay a great dark forest, and under an old lime-tree in the forest was a well, and when the day was very warm, the king's child went out into the forest and sat down by the side of the cool fountain, and when she was bored she took a golden ball, and threw it up on high and caught it, and this ball was her favorite plaything."

input "Width"; width ' user specifies width

while word$(doc$,i + 1," ") <> ""

 i = i + 1
 thisWord$ = word$(doc$,i," ") + " "
 if word$(thisWord$,2,chr$(13)) <> "" then thisWord$ = word$(thisWord$,2,chr$(13)) + " " ' strip the <CR>
 if len(docOut$) + len(thisWord$) > width then
   print docOut$
   docOut$ = ""
 end if
 docOut$ = docOut$ + thisWord$

wend print docOut$</lang>

Seed7

<lang seed7>$ include "seed7_05.s7i";

const func string: wrap (in string: aText, in integer: lineWidth) is func

 result
   var string: wrapped is "";
 local
   var array string: words is 0 times "";
   var string: word is "";
   var integer: spaceLeft is 0;
 begin
   words := split(aText, " ");
   if length(words) <> 0 then
     wrapped := words[1];
     words := words[2 ..];
     spaceLeft := lineWidth - length(wrapped);
     for word range words do
       if length(word) + 1 > spaceLeft then
         wrapped &:= "\n" & word;
         spaceLeft := lineWidth - length(word);
       else
         wrapped &:= " " & word;
         spaceLeft -:= 1 + length(word);
       end if;
     end for;
   end if;
 end func;

const proc: main is func

 local
   const string: frog is "In olden times when wishing still helped one, there lived \
       \a king whose daughters were all beautiful, but the youngest was so beautiful \
       \that the sun itself, which has seen so much, was astonished whenever it \
       \shone in her face. Close by the king's castle lay a great dark forest, and \
       \under an old lime-tree in the forest was a well, and when the day was very \
       \warm, the king's child went out into the forest and sat down by the side of \
       \the cool fountain, and when she was bored she took a golden ball, and threw \
       \it up on high and caught it, and this ball was her favorite plaything.";
   var integer: width is 0;
 begin 
   for width range [] (72, 80) do
     writeln("Wrapped at " <& width <& ":");
     writeln(wrap(frog, width));
   end for;
 end func;</lang>
Output:
Wrapped at 72:
In olden times when wishing still helped one, there lived a king whose
daughters were all beautiful, but the youngest was so beautiful that the
sun itself, which has seen so much, was astonished whenever it shone in
her face. Close by the king's castle lay a great dark forest, and under
an old lime-tree in the forest was a well, and when the day was very
warm, the king's child went out into the forest and sat down by the side
of the cool fountain, and when she was bored she took a golden ball, and
threw it up on high and caught it, and this ball was her favorite
plaything.
Wrapped at 80:
In olden times when wishing still helped one, there lived a king whose daughters
were all beautiful, but the youngest was so beautiful that the sun itself, which
has seen so much, was astonished whenever it shone in her face. Close by the
king's castle lay a great dark forest, and under an old lime-tree in the forest
was a well, and when the day was very warm, the king's child went out into the
forest and sat down by the side of the cool fountain, and when she was bored she
took a golden ball, and threw it up on high and caught it, and this ball was her
favorite plaything.

Tcl

Using a simple greedy algorithm to wrap the same text as used in the Go solution. Note that it assumes that the line length is longer than the longest word length. <lang tcl>package require Tcl 8.5

proc wrapParagraph {n text} {

   regsub -all {\s+} [string trim $text] " " text
   set RE "^(.{1,$n})(?:\\s+(.*))?$"
   for {set result ""} {[regexp $RE $text -> line text]} {} {

append result $line "\n"

   }
   return [string trimright $result "\n"]

}

set txt \ "In olden times when wishing still helped one, there lived a king whose daughters were all beautiful, but the youngest was so beautiful that the sun itself, which has seen so much, was astonished whenever it shone in her face. Close by the king's castle lay a great dark forest, and under an old lime-tree in the forest was a well, and when the day was very warm, the king's child went out into the forest and sat down by the side of the cool fountain, and when she was bored she took a golden ball, and threw it up on high and caught it, and this ball was her favorite plaything."

puts "[string repeat - 80]" puts [wrapParagraph 80 $txt] puts "[string repeat - 72]" puts [wrapParagraph 72 $txt]</lang>

Output:
--------------------------------------------------------------------------------
In olden times when wishing still helped one, there lived a king whose daughters
were all beautiful, but the youngest was so beautiful that the sun itself, which
has seen so much, was astonished whenever it shone in her face. Close by the
king's castle lay a great dark forest, and under an old lime-tree in the forest
was a well, and when the day was very warm, the king's child went out into the
forest and sat down by the side of the cool fountain, and when she was bored she
took a golden ball, and threw it up on high and caught it, and this ball was her
favorite plaything.
------------------------------------------------------------------------
In olden times when wishing still helped one, there lived a king whose
daughters were all beautiful, but the youngest was so beautiful that the
sun itself, which has seen so much, was astonished whenever it shone in
her face. Close by the king's castle lay a great dark forest, and under
an old lime-tree in the forest was a well, and when the day was very
warm, the king's child went out into the forest and sat down by the side
of the cool fountain, and when she was bored she took a golden ball, and
threw it up on high and caught it, and this ball was her favorite
plaything.

TPP

The text presentation program automatically provides word wrap:

<lang tpp> The kings youngest daughter was so beautiful that the sun itself, which has seen so much, was astonished whenever it shone in her face.</lang>

TUSCRIPT

<lang tuscript> $$ MODE TUSCRIPT text="In olden times when wishing still helped one, there lived a king whose daughters were all beautiful, but the youngest was so beautiful that the sun itself, which has seen so much, was astonished whenever it shone in her face. Close by the king's castle lay a great dark forest, and under an old lime-tree in the forest was a well, and when the day was very warm, the king's child went out into the forest and sat down by the side of the cool fountain, and when she was bored she took a golden ball, and threw it up on high and caught it, and this ball was her favorite plaything."

ERROR/STOP CREATE ("text",seq-E,-std-)

length=80 line=REPEAT ("-",length) FILE "text" = line firstline=nextlines="" wrappedtext=FORMAT(text,length,firstline,nextlines) FILE "text" = wrappedtext

length=72 line=REPEAT ("-",length) FILE "text" = line firstline=CONCAT ("Length ",length,": ") wrappedtext=FORMAT(text,length,firstline,nextlines) FILE "text" = wrappedtext </lang> Output:

--------------------------------------------------------------------------------
In olden times when wishing still helped one, there lived a king whose daughters
were all beautiful, but the youngest was so beautiful that the sun itself, which
has seen so much, was astonished whenever it shone in her face.  Close by the
king's castle lay a great dark forest, and under an old lime-tree in the forest
was a well, and when the day was very warm, the king's child went out into the
forest and sat down by the side of the cool fountain, and when she was bored she
took a golden ball, and threw it up on high and caught it, and this ball was her
favorite plaything.
------------------------------------------------------------------------
Length 72: In olden times when wishing still helped one, there lived a
king whose daughters were all beautiful, but the youngest was so
beautiful that the sun itself, which has seen so much, was astonished
whenever it shone in her face.  Close by the king's castle lay a great
dark forest, and under an old lime-tree in the forest was a well, and
when the day was very warm, the king's child went out into the forest
and sat down by the side of the cool fountain, and when she was bored
she took a golden ball, and threw it up on high and caught it, and this
ball was her favorite plaything.