[m-rev.] for review: add string.word_wrap/2

Ian MacLarty maclarty at cs.mu.OZ.AU
Sun Mar 13 19:58:38 AEDT 2005


On Sun, Mar 13, 2005 at 03:41:23PM +1100, Julien Fischer wrote:
> 
> On Sat, 12 Mar 2005, Ian MacLarty wrote:
> 
> > How do I adjust the NEWS file for this?  I don't want to include this in
> > the 0.12 release, but it should go in the news for the 0.13 release.
> >
> Just put a temporary section at the top of the NEWS file on the main
> branch. e.g. Changes since 0.12 fork, and put any changes there.  I'll
> clean it all up closer to the release.
> 

Okay:
Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.375
diff -u -r1.375 NEWS
--- NEWS	25 Feb 2005 08:02:09 -0000	1.375
+++ NEWS	13 Mar 2005 08:36:56 -0000
@@ -1,3 +1,8 @@
+NEWS since Mercury release 0.12.0:
+----------------------------------
+
+* We have added string.word_wrap/2.
+
 NEWS since Mercury release 0.11.0:
 ----------------------------------
 
I've also added NEWS to the cvs log file.

> > 	type after format_table function, since poly_type is after
> > 	the format function.
> It would be clearer to just say that you have rearranged this items
> so that they are now in top-down order.
> 

Okay.

> >
> > tests/general/string_test.exp
> > tests/general/string_test.m
> > 	Test string.word_wrap/2.
> >
> > Index: library/string.m
> > ===================================================================
> > RCS file: /home/mercury1/repository/mercury/library/string.m,v
> > retrieving revision 1.230
> > diff -u -r1.230 string.m
> > --- library/string.m	28 Feb 2005 03:39:38 -0000	1.230
> > +++ library/string.m	12 Mar 2005 08:28:23 -0000
> > @@ -670,20 +670,12 @@
> >  :- pred string__format(string::in, list(string__poly_type)::in, string::out)
> >  	is det.
> >
> > -%------------------------------------------------------------------------------%
> > -
> >  :- type string__poly_type
> >  	--->	f(float)
> >  	;	i(int)
> >  	;	s(string)
> >  	;	c(char).
> >
> > -%-----------------------------------------------------------------------------%
> > -
> > -:- type justified_column
> > -	--->	left(list(string))
> > -	;	right(list(string)).
> > -
> >  	% format_table(Columns, Separator) = Table
> >  	% format_table/2 takes a list of columns and a column separator
> >  	% and returns a formatted table, where each field in each column
> > @@ -703,6 +695,19 @@
> >  	%
> >  :- func string__format_table(list(justified_column), string) = string.
> >
> > +:- type justified_column
> > +	--->	left(list(string))
> > +	;	right(list(string)).
> > +
> > +	% word_wrap(Str, N) = Wrapped.
> > +	% Wrapped is Str with newlines inserted between words so that at most
> > +	% N characters appear on a line and each line contains as many
> > +	% whole words as possible.  If any one word exceeds N characters in
> > +	% length then it will be broken over two (or more) lines.
> I think that you should be able to insert a hyphen between the two parts
> of the word in this case.  (Perhaps, make this an optional argument).

I don't think this'll be particularly useful since words that are longer than
a line typically aren't real words anyway.  Also I don't want to spend any
more time on this - I have bigger and better things to do...  You feel free
to add this feature if you feel you need it though ;-)

> 
> 
> > +	% Multiple successive whitespaces are also replaced with one space.
> > +	%
> I suggest:
> 
> 	Sequences of whitspace characters are replaced by a single space.
> 

Fine.

> > +:- func string__word_wrap(string, int) = string.
> > +
> >  %-----------------------------------------------------------------------------%
> >
> >  :- implementation.
> > @@ -4714,6 +4719,66 @@
> >
> >  %-----------------------------------------------------------------------------%
> >
> > +string__word_wrap(Str, N) = Wrapped :-
> > +	Words = string.words(char.is_whitespace, Str),
> > +	string.word_wrap_2(Words, 1, N, [], Wrapped).
> > +
> > +:- pred word_wrap_2(list(string)::in, int::in, int::in, list(string)::in,
> > +	string::out) is det.
> > +
> > +word_wrap_2([], _, _, RevStrs, string.join_list("", list.reverse(RevStrs))).
> > +word_wrap_2([Word | Words], Col, N, Prev, Wrapped) :-
> > +	WordLen = string.length(Word),
> > +	(
> > +		Col = 1, WordLen < N
> > +	->
> > +		word_wrap_2(Words, Col + WordLen, N, [Word | Prev], Wrapped)
> > +	;
> > +		Col + 1 + WordLen < N
> > +	->
> > +		word_wrap_2(Words, Col + WordLen + 1, N, [Word, " " | Prev],
> > +			Wrapped)
> > +	;
> > +		Col + 1 + WordLen = N
> > +	->
> > +		word_wrap_2(Words, 1, N, ["\n", Word, " " | Prev], Wrapped)
> > +	;
> > +		(
> > +			Col = 1, WordLen > N
> > +		->
> > +			%
> > +			% Break up words that are too big to fit on a line.
> > +			%
> > +			RevPieces = break_up_rev(Word, N, []),
> > +			(
> > +				RevPieces = [LastPiece | _]
> > +			;
> > +				RevPieces = [],
> > +				error("string__word_wrap_2: no pieces")
> > +			),
> > +			PiecesStr = string.join_list("\n", list.reverse(
> > +				RevPieces)),
> > +			word_wrap_2(Words, string.length(LastPiece), N,
> > +				[PiecesStr | Prev], Wrapped)
> > +		;
> > +			word_wrap_2([Word | Words], 1, N, ["\n" | Prev],
> > +			Wrapped)
> > +		)
> > +	).
> > +
> > +:- func break_up_rev(string, int, list(string)) = list(string).
> > +
> I suggest renaming this predicate break_up_reversed_string.
> 

That's a bit misleading since the string isn't reversed - the returned list is.
I renamed it to break_up_string_reverse.

> > +break_up_rev(Str, N, Prev) = Strs :-
> > +	(
> > +		string.length(Str) =< N
> It may be worth keeping track of the length of the strings as you go,
> rather than recomputing it all the time.
> 

I doubt it, since it won't be very often that a word needs to be broken up over
multiple lines (with english text and a sensible line width at least).

Ian.
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list