Word wrap

From Rosetta Code
Revision as of 06:34, 30 March 2012 by rosettacode>CRGreathouse (GP)
Word wrap is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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.

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.

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.

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.

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.