Hello,
can anyone point me to some piece of code that do text
justification of fixed fonts like those that nroff do on manpages?
Thanks,
Gaetano
here's a routine to get you started. This doesn't do justifications,
but it will start you on the way.
This shouldn't violate too many std C rules. 8^)
/*
** START DOC
**
** wordwrap()
**
** Ed Prochak
** 1 June 1995
**
** The wordwrap function splits the input string at whitespace
** which is at the wrap position specified or less (ie left).
** The string is truncated at the wrap point if no whitespace
** is found within wrap margin (wrap_mgn) characters.
** (Sorry, it does not hyphenate!)
** If the wrap margin value is zero, this routine will simply
** truncate the string at the wrap point. The function returns
** a pointer value which indicates the location within the input
** string just after the last character that was copied to the
** output string. This allows the caller to set up a loop to
** repeatedly call this function to split a string multiple times.
**
**
** Parameters :-
** instring - pointer to the current position for the
** input text string
** wrap_pnt - the wrap point specifies the last position
** in the output field. It is the length of the
** output string minus one.
** wrap_mgn - the wrap margin specifies the backup limit
** in searching for whitespace for spliting the
** line. If no whitespace is found within this many
** characters, the string is merely truncated at
** the wrap point.
** outstring - output string is a copy of the input from
** position 0 to the wrap_pnt (or less)
**
** Return Value :-
** the function returns a pointer to the place in the input
** string which immediately follows the last character moved
** to the output string. This allows repeated calls to split a
** large string multiple times.
** Errors :-
** A null pointer value is returned in case of an error.
** Possible errors include:
** a null pointer value for either instring or outstring,
** instring and outstring pointing to the same location,
** a wrap margin that may back up too far,
** a wrap margin or wrap point that is negative,
** or zero value for the wrap point.
**
** Example :-
**
** Suppose the requirement is to print a column 14 character wide
** and allows words longer than 3 charaters to be split. Then
** given an input string:
**
** ls =
** "12345678901234 long string with tabs ., and more_such_junk"
**
** the following code:
**
** char part[15]
** char *s=&ls
** do {
** s = wordwrap( s, 14, 3, part )
** printf("*%14s*\n",part)
** }
** while ( *s!='\0' ) {
**
** will print:
**
** *12345678901234*
** * long string*
** * with tabs .,*
** * and more_such*
** *_junk*
**
** ----------------------------------------------------------
** The diagram below should illustrate the wrap margin value.
**
** this places the wrap point here!
** ^ ^ ^
** | | |
** | wrap_mgn=4 --+ +--- wrap_pnt=32
** |
** +----wrap_mgn=20
**
** ----------------------------------------------------------
**
** Assumptions :-
** == the output string is assumed to be at least as long as
** wrap_pnt+1 where the extra position will be filled with
** the string terminator.
** == whitespace characters are assumed to include all
** characters with binary values less than or equal to
** the blank ' ' character.
**
** END DOC
*/
#ifndef NULL
#define NULL ((char *)0)
#endif
/**********/
char *wordwrap(
char *instring,
int wrap_pnt,
int wrap_mgn,
char *outstring )
{
int i;
char *in;
char *out;
/* PERFORM SANITY CHECKS - MAKE SURE WE DON'T PARSE GARBAGE */
if( instring == outstring ) return (NULL);
if( NULL == instring ) return (NULL);
if( NULL == outstring ) return (NULL);
if( wrap_pnt < wrap_mgn ) return (NULL);
if( wrap_pnt < 1 ) return (NULL);
if( wrap_mgn < 0 ) return (NULL);
/* START WITH A SIMPLEMINDED COPY */
in = instring;
out = outstring;
for ( i=0; i<wrap_pnt; i++ )
{
if ( '\0'==*in ) break;
*out = *in;
out++; in++;
}
*out='\0';
/* DID WE REACH THE END OF INPUT BEFORE THE FILLING THE OUTPUT? */
/* IF YES, JUST RETURN THE END OF STRING LOCATION. */
if ( '\0'==*in ) return (in);
/* THE OUTPUT BUFFER IS FULL, BACK UP TO FIND THE SPLIT POINT */
for ( i=0; i<wrap_mgn; i++, in-- )
{
/* IF WHITESPACE FOUND THEN MAKE THE BREAK */
if ( *in <= ' ' ) break;
}
/* IF NO WHITESPACE TO SPLIT ON, THEN TRUNCATE */
if ( i==wrap_mgn )
{
i=0 ;
in=in+wrap_mgn;
}
out=out-i; /* BACKUP TO THE WHITESPACE */
*out='\0'; /* OVERWRITE THE WHITESPACE CHAR. WITH TERMINATOR */
return(in);
}
/******************************************************************/