Jump to content

Word wrap: Difference between revisions

→‎{{header|Ada}}: Added Ada version
m (→‎{{header|REXX}}: added/changed comments, added whitespace. -- ~~~~)
(→‎{{header|Ada}}: Added Ada version)
Line 8:
 
If you have both basic and extra credit solutions, show an example where the two algorithms give different results.
 
=={{header|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):
 
 
<pre>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.</pre>
 
For the extra credit, one could derive a class Word_Wrap.Advanced from Word_Wrap.Basic.
 
=={{header|AWK}}==
Line 58 ⟶ 208:
awk -f wordwrap.awk -v width=80 &lt; text.txt
</pre>
 
=={{header|C}}==
<lang c>#include <stdio.h>
Anonymous user
Cookies help us deliver our services. By using our services, you agree to our use of cookies.