Word wrap: Difference between revisions
No edit summary |
m →{{header|Sidef}}: modified the code to work with the latest version of Sidef |
||
Line 2,977: | Line 2,977: | ||
for (var i = 0 ; i <= array.end ; i++) { |
for (var i = 0 ; i <= array.end ; i++) { |
||
var word_len = array[i].len; |
|||
len += word_len; |
|||
len > WIDTH && ( |
len > WIDTH && ( |
||
Line 2,988: | Line 2,989: | ||
); |
); |
||
root.append(Hash.new(array |
root.append(Hash.new(array.ft(0, i).join(" ") |
||
=> self.prepare_words(array |
=> self.prepare_words(array.ft(i + 1, array.end)))); |
||
++len >= WIDTH && break; |
++len >= WIDTH && break; |
||
} |
} |
||
root ? root : |
root ? root : Null; |
||
} |
} |
||
Line 3,030: | Line 3,031: | ||
} |
} |
||
score < best |
score < best{:score} && ( |
||
best |
best{:score} = score; |
||
best |
best{:value} = array_ref; |
||
); |
); |
||
} |
} |
||
best |
best{:value}; |
||
} |
} |
||
Revision as of 00:38, 27 October 2015
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
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.
AutoHotkey
Basic word-wrap. Formats text that has been copied to the clipboard. <lang AutoHotkey>MsgBox, % "72`n" WrapText(Clipboard, 72) "`n`n80`n" WrapText(Clipboard, 80) return
WrapText(Text, LineLength) { StringReplace, Text, Text, `r`n, %A_Space%, All while (p := RegExMatch(Text, "(.{1," LineLength "})(\s|\R+|$)", Match, p ? p + StrLen(Match) : 1)) Result .= Match1 ((Match2 = A_Space || Match2 = A_Tab) ? "`n" : Match2) return, Result }</lang>
- Output:
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. 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.
Note: AutoHotkey can automatically word-wrap text in GUI controls such as text, edit boxes, buttons, etc. But, the word-wrap width is based on pixels, not characters.
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
Batch File
Basic word wrap.
@echo off setlocal enabledelayedexpansion %== Setting the new line character ==% set ^"nl=^ ^" %== The blank line above is required... ==% set "input=Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur." %== Call the Function (The second parameter is the line width) ==% call :wrap "%input%" 40 call :wrap "%input%" 70 pause>nul exit /b 0 %== The Function... ==% :wrap set output=&set limit= set tmp_str=%~1&set width=%2 :proc_loop %== Check if we're already done ==% if "!tmp_str!"=="" ( echo. echo !output! goto :EOF ) %== If not yet done, scan the next word... ==% for /f "tokens=1,* delims= " %%A in ("!tmp_str!") do ( set tmp_str=%%B&set word=%%A&set str=%%A %== The next line is an alternative for counting the word length ==% set leng=0&if not "!str!"=="" for /l %%. in (0,1,1000) do if not "!str:~%%.,1!"=="" set /a leng+=1 set /a "limit+=!leng!" %== Check if we should make a new line or not... ==% if !limit! gtr !width! ( set /a limit=!leng!+1 set "output=!output!!nl!!word! " ) else ( set /a limit+=1 set "output=!output!!word! " ) ) goto proc_loop
- Output:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
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 rem . !arg:(?txt.?length) & :?output & whl ' ( @( str$!txt : ?line (" " %?lastword [?q " " ?rem&!q:~<!length) ) & !lastword " " !rem:?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 her favorite 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 this ball was her favorite plaything.
C
<lang c>#include <stdio.h>
- include <stdlib.h>
- include <string.h>
- 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.
- /
- define PENALTY_LONG 100
- 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.
<lang cpp>#include <iostream>
- include <sstream>
- 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.
<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.
Elixir
<lang elixir>defmodule Word_wrap do
def paragraph( string, max_line_length ) do [word | rest] = String.split( string, ~r/\s+/, trim: true ) lines_assemble( rest, max_line_length, String.length(word), word, [] ) |> Enum.join( "\n" ) end defp lines_assemble( [], _, _, line, acc ), do: [line | acc] |> Enum.reverse defp lines_assemble( [word | rest], max, line_length, line, acc ) do if line_length + 1 + String.length(word) > max do lines_assemble( rest, max, String.length(word), word, [line | acc] ) else lines_assemble( rest, max, line_length + 1 + String.length(word), line <> " " <> word, acc ) end end
end
text = """ 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. """ Enum.each([72, 80], fn len ->
IO.puts String.duplicate("-", len) IO.puts Word_wrap.paragraph(text, len)
end)</lang>
- Output:
------------------------------------------------------------------------ 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.
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#
<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.
Groovy
<lang groovy>def wordWrap(text, length = 80) {
def sb = new StringBuilder() def line =
text.split(/\s/).each { word -> if (line.size() + word.size() > length) { sb.append(line.trim()).append('\n') line = } line += " $word" } sb.append(line.trim()).toString()
}</lang> Testing: <lang groovy>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.""".stripIndent().split('\n').join(' ')
println wordWrap(text) println wordWrap(text, 120)</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.
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>
Alternative greedy wrapping: <lang haskell>import Data.List
teststring = "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."
wwrap _ [] = [] wwrap i ss = (\(a,b) -> a : wwrap i b) $ last . filter ((<=i) . length . unwords . fst) $ zip (inits ss) (tails ss)
wwrap :: Int -> String -> String wwrap i = unlines . map unwords . wwrap i . words . concat . lines
main = putStrLn $ wwrap 80 teststring</lang>
Icon and Unicon
The following works in both languages.
<lang unicon> procedure main(A)
ll := integer(A[1]) | 72 wordWrap(&input, ll)
end
procedure wordWrap(f, ll)
every (sep := "", s := "", w := words(f)) do if w == "\n" then write(1(.s, s := sep := ""),"\n") else if (*s + *w) >= ll then write(1(.s, s := w, sep := " ")) else (s ||:= .sep||("\n" ~== w), sep := " ") if *s > 0 then write(s)
end
procedure words(f)
static wc initial wc := &cset -- ' \t' # Loose definition of a 'word'... while l := !f do { l ? while tab(upto(wc)) do suspend tab(many(wc))\1 if *trim(l) = 0 then suspend "\n" # Paragraph boundary }
end</lang>
Sample runs:
->ww <ww.icn procedure main(A) ll := integer(A[1]) | 72 wordWrap(&input, ll) end procedure wordWrap(f, ll) every (sep := "", s := "", w := words(f)) do if w == "\n" then write(1(.s, s := sep := ""),"\n") else if (*s + *w) >= ll then write(1(.s, s := w, sep := " ")) else (s ||:= .sep||("\n" ~== w), sep := " ") if *s > 0 then write(s) end procedure words(f) static wc initial wc := &cset -- ' \t' # Loose definition of a 'word'... while l := !f do { l ? while tab(upto(wc)) do suspend tab(many(wc))\1 if *trim(l) = 0 then suspend "\n" # Paragraph boundary } end ->ww 50 <ww.icn procedure main(A) ll := integer(A[1]) | 72 wordWrap(&input, ll) end procedure wordWrap(f, ll) every (sep := "", s := "", w := words(f)) do if w == "\n" then write(1(.s, s := sep := ""),"\n") else if (*s + *w) >= ll then write(1(.s, s := w, sep := " ")) else (s ||:= .sep||("\n" ~== w), sep := " ") if *s > 0 then write(s) end procedure words(f) static wc initial wc := &cset -- ' \t' # Loose definition of a 'word'... while l := !f do { l ? while tab(upto(wc)) do suspend tab(many(wc))\1 if *trim(l) = 0 then suspend "\n" # Paragraph boundary } end ->
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>
JavaScript
Solution:<lang javascript> function wrap (text, limit) {
if (text.length > limit) { // find the last space within limit var edge = text.slice(0, limit).lastIndexOf(' '); if (edge > 0) { var line = text.slice(0, edge); var remainder = text.slice(edge + 1); return line + '\n' + wrap(remainder, limit); } } return text;
} </lang> Example:<lang javascript> console.log(wrap(text, 80)); </lang>
- Output:
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.
Example:<lang javascript> console.log(wrap(text, 42)); </lang>
- Output:
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.
jq
The following implementation requires a version of jq with splits/1, for splitting on whitespace.
In jq, all strings are Unicode strings, for which the length is calculated as the number of codepoints. <lang jq># Simple greedy algorithm.
- Note: very long words are not truncated.
- input: a string
- output: an array of strings
def wrap_text(width):
reduce splits("\\s+") as $word ([""]; .[length-1] as $current | ($word|length) as $wl | (if $current == "" then 0 else 1 end) as $pad | if $wl + $pad + ($current|length) <= width then .[-1] += ($pad * " ") + $word else . + [ $word] end );</lang>
Task 1: <lang jq>"aaa bb cc ddddd" | wrap_text(6)[] # wikipedia example</lang>
- Output:
aaa bb cc ddddd
Task 2: <lang jq>"aaa bb cc ddddd" | wrap_text(5)[]</lang>
- Output:
aaa bb cc ddddd
With input from a file: Russian.txt
<lang sh>советских военных судов и самолетов была отмечена в Японском море после появления там двух американских авианосцев. Не менее 100 советских самолетов поднялись в воздух, когдаамериканские авианосцы "Уинсон" и "Мидуэй" приблизились на 50 миль к Владивостоку.
</lang>Main:
wrap_text(40)[]
- Output:
<lang sh>$ jq -M -R -s -r -f Word_wrap.jq Russian.txt советских военных судов и самолетов была отмечена в Японском море после появления там двух американских авианосцев. Не менее 100 советских самолетов поднялись в воздух, когдаамериканские авианосцы "Уинсон" и "Мидуэй" приблизились на 50 миль к Владивостоку. </lang>
Lasso
<lang Lasso>define wordwrap(
text::string,
row_length::integer = 75
) => {
return regexp(`(?is)(.{1,` + #row_length + `})(?:$|\W)+`, '$1
\n', #text, true) -> replaceall
}
local(text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris consequat ornare lectus, dignissim iaculis libero consequat sed. Proin quis magna in arcu sagittis consequat sed ac risus. Ut a pharetra dui. Phasellus molestie, mauris eget scelerisque laoreet, diam dolor vulputate nulla, in porta sem sem sit amet lacus.')
wordwrap(#text, 40)
'
'
wordwrap(#text)
'
'
wordwrap(#text, 90)</lang>
->
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris consequat ornare lectus, dignissim iaculis libero consequat sed. Proin quis magna in arcu sagittis consequat sed ac risus. Ut a pharetra dui. Phasellus molestie, mauris eget scelerisque laoreet, diam dolor vulputate nulla, in porta sem sem sit amet lacus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris consequat ornare lectus, dignissim iaculis libero consequat sed. Proin quis magna in arcu sagittis consequat sed ac risus. Ut a pharetra dui. Phasellus molestie mauris eget scelerisque laoreet, diam dolor vulputate nulla, in porta sem sem sit amet lacus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris consequat ornare lectus, dignissim iaculis libero consequat sed. Proin quis magna in arcu sagittis consequat sed ac risus. Ut a pharetra dui. Phasellus molestie, mauris eget scelerisque laoreet, diam dolor vulputate nulla, in porta sem sem sit amet lacus.
LFE
Naive Implementation
<lang Lisp> (defun wrap-text (text)
(wrap-text text 78))
(defun wrap-text (text max-len)
(string:join (make-wrapped-lines (string:tokens text " ") max-len) "\n"))
(defun make-wrapped-lines
(((cons word rest) max-len) (let ((`#(,_ ,_ ,last-line ,lines) (assemble-lines max-len word rest))) (lists:reverse (cons last-line lines)))))
(defun assemble-lines (max-len word rest)
(lists:foldl #'assemble-line/2 `#(,max-len ,(length word) ,word ()) rest))
(defun assemble-line
((word `#(,max ,line-len ,line ,acc)) (when (> (+ (length word) line-len) max)) `#(,max ,(length word) ,word ,(cons line acc))) ((word `#(,max ,line-len ,line ,acc)) `#(,max ,(+ line-len 1 (length word)) ,(++ line " " word) ,acc)))
</lang>
Regex Implementation
<lang lisp> (defun make-regex-str (max-len)
(++ "(.{1," (integer_to_list max-len) "}|\\S{" (integer_to_list (+ max-len 1)) ",})(?:\\s[^\\S\\r\\n]*|\\Z)"))
(defun wrap-text (text max-len)
(let ((find-patt (make-regex-str max-len)) (replace-patt "\\1\\\n")) (re:replace text find-patt replace-patt '(global #(return list)))))
</lang>
Usage examples:
<lang Lisp> > (set test-text (++ "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:format (wrap-text text 80)) </lang>
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. ok
<lang lisp> > (io:format (wrap-text text 50)) </lang>
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. ok
Lua
<lang lua>function splittokens(s)
local res = {} for w in s:gmatch("%S+") do res[#res+1] = w end return res
end
function textwrap(text, linewidth)
if not linewidth then linewidth = 75 end
local spaceleft = linewidth local res = {} local line = {}
for _, word in ipairs(splittokens(text)) do if #word + 1 > spaceleft then table.insert(res, table.concat(line, ' ')) line = {word} spaceleft = linewidth - #word else table.insert(line, word) spaceleft = spaceleft - (#word + 1) end end
table.insert(res, table.concat(line, ' ')) return table.concat(res, '\n')
end
local example1 = [[ 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. ]]
print(textwrap(example1)) print() print(textwrap(example1, 60))</lang>
- Output:
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.
Mathematica
<lang Mathematica>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."; wordWrap[textWidth_,spaceWidth_,string_]:=Module[{start,spaceLeft,masterString},
spaceLeft=textWidth; start=1; masterString={}; Do[ If[i+1>Length@StringSplit@string , p=StringSplit[string]start;;i; AppendTo[masterString,{StringJoin@@Riffle[p,StringJoin@ConstantArray[" ",spaceWidth]]}] , If[StringLength[StringSplit@string]i+1+spaceWidth>spaceLeft , spaceLeft=textWidth-StringLength[StringSplit@string]i; start=i; AppendTo[masterString,{StringJoin@@Riffle[p,StringJoin@ConstantArray[" ",spaceWidth]]}] , spaceLeft-=StringLength[StringSplit@string]i; spaceLeft-=spaceWidth; p=StringSplit[string]start;;i ] ] , {i,1,Length@StringSplit@string} ]; StringJoin@@Riffle[masterString,"\n"]
];</lang>
- Output:
for width 72 and 80
<lang>wordWrap[72, 1, string] wordWrap[80, 1, string]</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.
NetRexx
version 1
<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)
version 2
<lang NetRexx>/* NetRexx ************************************************************
- 23.08.2013 Walter Pachl translated from REXX version 2
- /
options replace format comments java crossref symbols
runSample(arg)
method runSample(arg) public static
s='She should have died hereafter;' - 'There would have been a time for such a word.' - 'Tomorrow, and tomorrow, and tomorrow, and so on' w=72 Say s.length loop while s>' ' Loop i=w+1 to 1 by -1 If s.substr(i,1)= Then Leave End If i=0 Then p=s.pos(' ') Else p=i say s.left(p) s=s.substr(p+1) End If s> Then say s return</lang>
Nim
<lang nim>import strutils
let txt = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur." echo wordWrap(txt) echo "" echo wordWrap(txt, 45) </lang>
- Output:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
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>
PL/I
<lang pli>*process source attributes xref or(!);
ww: proc Options(main); /********************************************************************* * 21.08-2013 Walter Pachl derived from REXX version 2 *********************************************************************/ Dcl in record input; Dcl out record output; On Endfile(in) z=' '; Dcl z char(32767) Var; Dcl s char(32767) Var Init(); dcl o Char(200) Var; Dcl (i,w,p) Bin Fixed(31) Init(0); w=72; Read File(in) Into(z); s=z; Do Until(s=); Do i=w+1 to 1 by -1; If substr(s,i,1)= Then Leave; End; If i=0 Then p=index(s,' '); Else p=i; o=left(s,p); Write file(out) From(o); s=substr(s,p+1); If length(s)<200 Then Do; Read File(in) Into(z); s=s!!z; End; End; End;</lang>
Test result using this:
/* REXX */ Call time 'R' 'set dd:in=h:\long2.txt,recsize(30000)' /* 1000036 characters with random length words */ 'set dd:out=h:\longp.72,recsize(300)' 'ww' Say time('E')
- Output:
A nnnnnnnnnnnnnn ooooooooooooooo nnnnnnnnnnnnnn ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc iiiiiiiii LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL etc.
PowerShell
Basic word wrap. <lang powershell>function wrap{ $divide=$args[0] -split " " $width=$args[1] $spaceleft=$width
foreach($word in $divide){ if($word.length+1 -gt $spaceleft){ $output+="`n$word " $spaceleft=$width-($word.length+1) } else { $output+="$word " $spaceleft-=$word.length+1 } }
return "$output`n" }
- The Main Thing...
$paragraph="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur."
"`nLine width:30`n" wrap $paragraph 30 "=========================================================" "Line width:100`n" wrap $paragraph 100
- End script</lang>
- Output:
Line width:30 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. ========================================================= Line width:100 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
PureBasic
<lang purebasic> DataSection
Data.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." EndDataSection
Procedure.i ww_pos(txt$,l.i)
While Mid(txt$,l,1)<>Chr(32) And l>0 And Len(txt$)>l : l-1 : Wend If l>0 : ProcedureReturn l : Else : ProcedureReturn Len(Trim(txt$)) : EndIf
EndProcedure
Procedure WriteLine(txt$,ls.i)
Shared d$,lw Select LCase(d$) Case "l" : PrintN(Mid(txt$,1,ls)) Case "r" : PrintN(RSet(Trim(Mid(txt$,1,ls)),lw,Chr(32))) EndSelect
EndProcedure
Procedure main(txt$,lw.i)
If Len(txt$) p=ww_pos(txt$,lw) : WriteLine(txt$,p) : ProcedureReturn main(LTrim(Right(txt$,Len(txt$)-p)),lw) EndIf
EndProcedure
Procedure.i MaxWordLen(txt$)
For i=1 To CountString(txt$,Chr(32))+1 wrd$=LTrim(StringField(txt$,i,Chr(32))) wrdl=Len(wrd$)+1 : If wrdl>l : l=wrdl : EndIf Next ProcedureReturn l
EndProcedure
OpenConsole() Read.s t$ Print("Input line width: ") : lw=Val(Input()) : minL=MaxWordLen(t$) If lw<minL : lw=minL : PrintN("Min. line width "+Str(lw-1)) : EndIf Print("Input direction l:left r:rigth ") Repeat : d$=Inkey() : Delay(50) : Until FindString("lr",d$,1,#PB_String_NoCase) : PrintN(d$+#CRLF$) main(t$,lw) : Input() </lang>
- Output:
Input line width: 40 Input direction l:left r:rigth l 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 line width: 40 Input direction l:left r:rigth r 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.
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. >>>
R
Use strwrap()
:
<lang rsplus>> x <- "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. "
> cat(paste(strwrap(x=c(x, "\n"), width=80), collapse="\n"))
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus.
Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec
consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero
egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem
lacinia consectetur.
> cat(paste(strwrap(x=c(x, "\n"), width=60), collapse="\n"))
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas
congue ligula ac quam viverra nec consectetur ante
hendrerit. Donec et mollis dolor. Praesent et diam eget
libero egestas mattis sit amet vitae augue. Nam tincidunt
congue enim, ut porta lorem lacinia consectetur.</lang>
Racket
Using a library function: <lang Racket>
- 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>
- 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
version 0
This version was the original (of version 1) and has no error checking and only does left-margin justification. <lang rexx>/*REXX pgm reads a file and displays it (with word wrap to the screen). */ parse arg iFID width /*get optional arguments from CL.*/ @= /*nullify the text (so far). */
do j=0 while lines(iFID)\==0 /*read from the file until E-O-F.*/ @=@ linein(iFID) /*append the file's text to @ */ end /*j*/
$=word(@,1)
do k=2 for words(@)-1; x=word(@,k) /*parse until text (@) exhausted.*/ _=$ x /*append it to the money and see.*/ if length(_)>width then do /*words exceeded the width? */ say $ /*display what we got so far. */ _=x /*overflow for the next line. */ end $=_ /*append this word to the output.*/ end /*k*/
if $\== then say $ /*handle any residual words. */
/*stick a fork in it, we're done.*/</lang>
- Output:
is the same as version 1 using the Left option (the default).
version 1
The input for this program is in a file (named LAWS.TXT).
The default width of the output is the current terminal width (normally, this would be the window's width).
If the terminal width (or window's width) is indeterminable, then 80 is used.
The width can be expressed as a percentage (i.e.: 50%) which signifies to use ½ of the terminal's width).
No hyphenation (or de-hyphenation) is attempted.
Words longer than the width of the output are acceptable and are shown (with no truncation), a simple change could be made to issue a notification.
Some rudimentary error checking is performed.
Types of word wrapping (justification) are (only the first character is significant):
Center: ◄centered► Right: ────────►right margin Left: left margin◄───────── Both: ◄───both margins────►
(Left is the default.)
This version was modified (for speed at the expense of simplicity) to accommodate faster processing of large files.
Instead of appending lines of a file to a character string, the words are picked off and stored in a stemmed array.
This decreases the amount of work that REXX has to do to retrieve (get) the next word in the (possibly) ginormous string.
<lang rexx>/*REXX pgm reads a file and displays it (with word wrap to the screen).*/
parse arg iFID width justify _ . /*get optional CL args.*/
if iFID= |iFID==',' then iFID ='LAWS.TXT' /*default input file ID*/
if width==|width==',' then width=linesize() /*Default? Use linesize*/
if width==0 then width=80 /*indeterminable width.*/
if right(width,1)=='%' then do /*handle % of width. */
width=translate(width,,'%') /*remove the %*/ width=linesize() * translate(width,,"%")%100 end
if justify==|justify==',' then justify='Left' /*Default? Use LEFT */ just=left(justify,1) /*only use first char of JUSTIFY.*/ upper just /*be able to handle mixed case. */ if pos(just,'BCLR')==0 then call err "JUSTIFY (3rd arg) is illegal:" justify if _\== then call err "too many arguments specified." _ if \datatype(width,'W') then call err "WIDTH (2nd arg) isn't an integer:" width n=0 /*number of words in the file. */
do j=0 while lines(iFID)\==0 /*read from the file until E-O-F.*/ _=linein(iFID) /*get a record (line of text). */ do words(_) /*extract some words (maybe not).*/ n=n+1; parse var _ @.n _ /*get & assign next word in text.*/ end /*DO words(_)*/ end /*j*/
if j==0 then call err 'file' iFID "not found." if n==0 then call err 'file' iFID "is empty (or has no words)" $=@.1 /*init da money bag with 1st word*/
do m=2 for n-1; x=@.m /*parse until text (@) exhausted.*/ _=$ x /*append it to the money and see.*/ if length(_)>width then call tell /*this word a bridge too far? >w*/ $=_ /*the new words are OK so far. */ end /*m*/
call tell /*handle any residual words. */ exit /*stick a fork in it, we're done.*/ /*──────────────────────────────────ERR subroutine──────────────────────*/ err: say; say '***error!***'; say; say arg(1); say; say; exit 13 /*──────────────────────────────────TELL subroutine─────────────────────*/ tell: if $== then return /*first word may be too long. */ if just=='L' then $= strip($) /*left ◄────────*/
else do w=max(width,length($)) /*don't truncate long words.*/ select when just=='R' then $= right($,w) /*──────► right */ when just=='B' then $=justify($,w) /*◄────both────►*/ when just=='C' then $= center($,w) /* ◄centered► */ end /*select*/ end
say $ /*show and tell, or write──►file?*/
_=x /*handle any word overflow. */
return /*go back and keep truckin'. */</lang>
This REXX program makes use of LINESIZE REXX program (or BIF) which is used to determine the screen width (or linesize) of the terminal (console).
The LINESIZE.REX REXX program is included here ──► LINESIZE.REX.
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-Additivity 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 Detroit, 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 indeterminacy 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
────────── 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-Additivity 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 Detroit, 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 indeterminacy 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
────────── 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-Additivity 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 Detroit, 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 indeterminacy 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
────────── 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-Additivity 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 Detroit, 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 indeterminacy 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.
version 2
<lang rexx>/* REXX ***************************************************************
- 20.08.2013 Walter Pachl "my way"
- 23.08.2013 Walter Pachl changed to use lastpos bif
- /
Parse Arg w oid=w'.xxx'; 'erase' oid Call o left(copies('123456789.',20),w) s='She should have died hereafter;' ,
'There would have been a time for such a word.' , 'Tomorrow, and tomorrow, and tomorrow, and so on'
Call ow s Exit ow:
Parse Arg s s=s' ' Do While length(s)>w i=lastpos(' ',s,w+1) /* instead of loop */ If i=0 Then p=pos(' ',s) Else p=i Call o left(s,p) s=substr(s,p+1) End If s> Then Call o s Return
o:Return lineout(oid,arg(1))</lang>
- Output:
for widths 72 and 9
123456789.123456789.123456789.123456789.123456789.123456789.123456789.12 She should have died hereafter; There would have been a time for such a word. Tomorrow, and tomorrow, and tomorrow, and so on 123456789 She should have died hereafter; There would have been a time for such a word. Tomorrow, and tomorrow, and tomorrow, and so on
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] i = j + 1 end para 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>
- 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.
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>
Scala
Intuitive approach
<lang scala>import java.util.StringTokenizer
object WordWrap extends App {
final val defaultLineWidth = 80 final val spaceWidth = 1
def letsWrap(text: String, lineWidth: Int = defaultLineWidth) = { println(s"\n\nWrapped at: $lineWidth") println("." * lineWidth) minNumLinesWrap(ewd, lineWidth) }
final def ewd = "Vijftig jaar geleden publiceerde Edsger Dijkstra zijn kortstepadalgoritme. Daarom een kleine ode" + " aan de in 2002 overleden Dijkstra, iemand waar we als Nederlanders best wat trotser op mogen zijn. Dijkstra was" + " een van de eerste programmeurs van Nederland. Toen hij in 1957 trouwde, werd het beroep computerprogrammeur door" + " de burgerlijke stand nog niet erkend en uiteindelijk gaf hij maar `theoretische natuurkundige’ op.\nZijn" + " beroemdste resultaat is het kortstepadalgoritme, dat de kortste verbinding vindt tussen twee knopen in een graaf" + " (een verzameling punten waarvan sommigen verbonden zijn). Denk bijvoorbeeld aan het vinden van de kortste route" + " tussen twee steden. Het slimme van Dijkstra’s algoritme is dat het niet alle mogelijke routes met elkaar" + " vergelijkt, maar dat het stap voor stap de kortst mogelijke afstanden tot elk punt opbouwt. In de eerste stap" + " kijk je naar alle punten die vanaf het beginpunt te bereiken zijn en markeer je al die punten met de afstand tot" + " het beginpunt. Daarna kijk je steeds vanaf het punt dat op dat moment de kortste afstand heeft tot het beginpunt" + " naar alle punten die je vanaf daar kunt bereiken. Als je een buurpunt via een nieuwe verbinding op een snellere" + " manier kunt bereiken, schrijf je de nieuwe, kortere afstand tot het beginpunt bij zo’n punt. Zo ga je steeds een" + " stukje verder tot je alle punten hebt gehad en je de kortste route tot het eindpunt hebt gevonden."
def minNumLinesWrap(text: String, LineWidth: Int) { val tokenizer = new StringTokenizer(text) var SpaceLeft = LineWidth while (tokenizer.hasMoreTokens) { val word: String = tokenizer.nextToken if ((word.length + spaceWidth) > SpaceLeft) { print("\n" + word + " ") SpaceLeft = LineWidth - word.length } else { print(word + " ") SpaceLeft -= (word.length + spaceWidth) } } }
letsWrap(ewd) letsWrap(ewd, 120)
} // 44 lines</lang>
- Output:
Wrapped at: 80................................................................................ Vijftig jaar geleden publiceerde Edsger Dijkstra zijn kortstepadalgoritme. Daarom een kleine ode aan de in 2002 overleden Dijkstra, iemand waar we als Nederlanders best wat trotser op mogen zijn. Dijkstra was een van de eerste programmeurs van Nederland. Toen hij in 1957 trouwde, werd het beroep computerprogrammeur door de burgerlijke stand nog niet erkend en uiteindelijk gaf hij maar `theoretische natuurkundige’ op. Zijn beroemdste resultaat is het kortstepadalgoritme, dat de kortste verbinding vindt tussen twee knopen in een graaf (een verzameling punten waarvan sommigen verbonden zijn). Denk bijvoorbeeld aan het vinden van de kortste route tussen twee steden. Het slimme van Dijkstra’s algoritme is dat het niet alle mogelijke routes met elkaar vergelijkt, maar dat het stap voor stap de kortst mogelijke afstanden tot elk punt opbouwt. In de eerste stap kijk je naar alle punten die vanaf het beginpunt te bereiken zijn en markeer je al die punten met de afstand tot het beginpunt. Daarna kijk je steeds vanaf het punt dat op dat moment de kortste afstand heeft tot het beginpunt naar alle punten die je vanaf daar kunt bereiken. Als je een buurpunt via een nieuwe verbinding op een snellere manier kunt bereiken, schrijf je de nieuwe, kortere afstand tot het beginpunt bij zo’n punt. Zo ga je steeds een stukje verder tot je alle punten hebt gehad en je de kortste route tot het eindpunt hebt gevonden.
Wrapped at: 120 ........................................................................................................................ Vijftig jaar geleden publiceerde Edsger Dijkstra zijn kortstepadalgoritme. Daarom een kleine ode aan de in 2002 overleden Dijkstra, iemand waar we als Nederlanders best wat trotser op mogen zijn. Dijkstra was een van de eerste programmeurs van Nederland. Toen hij in 1957 trouwde, werd het beroep computerprogrammeur door de burgerlijke stand nog niet erkend en uiteindelijk gaf hij maar `theoretische natuurkundige’ op. Zijn beroemdste resultaat is het kortstepadalgoritme, dat de kortste verbinding vindt tussen twee knopen in een graaf (een verzameling punten waarvan sommigen verbonden zijn). Denk bijvoorbeeld aan het vinden van de kortste route tussen twee steden. Het slimme van Dijkstra’s algoritme is dat het niet alle mogelijke routes met elkaar vergelijkt, maar dat het stap voor stap de kortst mogelijke afstanden tot elk punt opbouwt. In de eerste stap kijk je naar alle punten die vanaf het beginpunt te bereiken zijn en markeer je al die punten met de afstand tot het beginpunt. Daarna kijk je steeds vanaf het punt dat op dat moment de kortste afstand heeft tot het beginpunt naar alle punten die je vanaf daar kunt bereiken. Als je een buurpunt via een nieuwe verbinding op een snellere manier kunt bereiken, schrijf je de nieuwe, kortere afstand tot het beginpunt bij zo’n punt. Zo ga je steeds een stukje verder tot je alle punten hebt gehad en je de kortste route tot het eindpunt hebt gevonden.
Process finished with exit code 0
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.
Sidef
Greedy: <lang ruby>class String {
method wrap(width) { var txt = self.gsub(/\s+/, " "); var len = txt.len; var para = []; var i = 0; while (i < len) { var j = (i + width); while ((j < len) && (txt.char_at(j) != ' ')) { --j }; para.append(txt.substr(i, j-i)); i = j+1; }; return para.join("\n"); }
}
var text = 'aaa bb cc ddddd'; say text.wrap(6);</lang>
- Output:
aaa bb cc ddddd
Smart: <lang ruby>class SmartWordWrap(WIDTH=80) {
method prepare_words(array) {
var root = []; var len = 0;
for (var i = 0 ; i <= array.end ; i++) { var word_len = array[i].len; len += word_len;
len > WIDTH && ( word_len > WIDTH && ( len -= word_len; array.splice(i, 1, array[i].split(WIDTH)...); --i; next; ); break; );
root.append(Hash.new(array.ft(0, i).join(" ") => self.prepare_words(array.ft(i + 1, array.end)))); ++len >= WIDTH && break; }
root ? root : Null; }
method combine(root, hash) {
var row = []; hash.each { |key, value| root.append(key);
if (value.is_an(Array)) { value.each { |item| row.append(self.combine(root, item)...); } } else { row = root...; }; root.pop; };
row; }
method find_best(arrays) {
var best = Hash.new( score => Math.inf, value => [], );
arrays.each { |array_ref| var score = 0;
array_ref.each { |string| score += Math.pow(WIDTH - string.len, 2); }
score < best{:score} && ( best{:score} = score; best{:value} = array_ref; ); }
best{:value}; }
method wrap(text) {
# Split the text into words text.is_a(String) && text.words!;
var lines = []; self.prepare_words(text).each { |path| lines.append(self.combine([], path)...); };
self.find_best(lines).join("\n"); }
}
var sww = SmartWordWrap(WIDTH: 6);
var words = %w(aaa bb cc ddddd); var wrapped = sww.wrap(words);
say wrapped;</lang>
- Output:
aaa bb cc ddddd
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.
VBScript
<lang vb> column = 60 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."
Call wordwrap(text,column)
Sub wordwrap(s,n) word = Split(s," ") row = "" For i = 0 To UBound(word) If Len(row) = 0 Then row = row & word(i) ElseIf Len(row & " " & word(i)) <= n Then row = row & " " & word(i) Else WScript.StdOut.WriteLine row row = word(i) End If Next If Len(row) > 0 Then WScript.StdOut.WriteLine row End If End Sub </lang>
- Output:
Wrapped at 60.
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.
zkl
This is a greedy algorithm for mono spaced text with ragged right. In addition, it can look at the first two lines to do "smart indenting". It handles multiple paragraphs and a variety of input sources. <lang zkl>fcn formatText(text, // text can be String,Data,File, -->Data
length=72, calcIndents=True){ sink:=Data(); getIndents:='wrap(w){ // look at first two lines to indent paragraph reg lines=L(), len=0, prefix="", one=True; do(2){
if(w._next()){ lines.append(line:=w.value); word:=line.split(Void,1)[0,1]; // get first word, if line !blank if(word){ p:=line[0,line.find(word[0]]); if(one){ sink.write(p); len=p.len(); one=False; } else prefix=p; } }
} w.push(lines.xplode()); // put first two lines back to be formated return(len,prefix); };
reg len=0, prefix="", w=text.walker(1); // lines if(calcIndents) len,prefix=getIndents(w); foreach line in (w){ if(not line.strip()){ // blank line
sink.write("\n",line); // blank line redux if(calcIndents) len,prefix=getIndents(w); else len=0; // restart formating
}else
len=line.split().reduce('wrap(len,word){ n:=word.len(); if(len==0) { sink.write(word); return(n); } nn:=n+1+len; if(nn<=length) { sink.write(" ",word); return(nn); } sink.write("\n",prefix,word); return(prefix.len()+word.len()); },len);
} sink
}</lang> <lang zkl>formatText(File("frog.txt")).text.println();</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 ...
Putting a bit of spit shine on the above and editing the source text to look like:
In olden times ...
<lang zkl>[1..].zipWith("%2d: %s".fmt,formatText(File("frog.txt")).walker(1)) .sink(String).walk().println();</lang>
- Output:
1: In olden times when wishing still helped one, there lived a king 2: whose daughters were all beautiful, but the youngest was so beautiful ... 9: favorite plaything.
<lang zkl>formatText("this\n is a test foo bar\n\ngreen eggs and spam",10).text.println();</lang>
- Output:
this is a test foo bar green eggs and spam
- Programming Tasks
- Solutions by Programming Task
- Text processing
- Ada
- AutoHotkey
- AWK
- Batch File
- Bracmat
- C
- C++
- C sharp
- Clojure
- D
- Elixir
- Erlang
- F Sharp
- Forth
- Go
- Groovy
- Haskell
- Icon
- Unicon
- J
- Java
- JavaScript
- Jq
- Lasso
- LFE
- Lua
- Mathematica
- NetRexx
- Nim
- OCaml
- PARI/GP
- Perl
- Perl 6
- PicoLisp
- PL/I
- PowerShell
- PureBasic
- Python
- R
- Racket
- REXX
- Ruby
- Run BASIC
- Scala
- Seed7
- Sidef
- Tcl
- TPP
- TUSCRIPT
- VBScript
- Zkl