text justification

G

gaetanoortisi

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
 
M

Mark Bluemel

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,

Have you tried to find the source code of nroff?
 
K

Kenny McCormack

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

I don't understand why you need to justify fixed fonts. As is the
standard advice in this ng when such questions arise, if you don't like
them, just don't use them.
 
R

Richard Tobin

can anyone point me to some piece of code that do text
justification of fixed fonts like those that nroff do on manpages?

Well, the code for nroff should be easy enough to find (look for
groff, the most widely-used implementation).

But I recommend not justifying with fixed width fonts. It's much
harder to read.

If you really want to do it, you fill the line with as many words as
will fit, then distribute the required number of extra spaces in the
gaps. You might use a version of Bressenham's algorithm (try Google)
for this.

-- Richard
 
K

Kenny McCormack

Well, the code for nroff should be easy enough to find (look for
groff, the most widely-used implementation).

But I recommend not justifying with fixed width fonts. It's much
harder to read.

If you really want to do it, you fill the line with as many words as
will fit, then distribute the required number of extra spaces in the
gaps. You might use a version of Bressenham's algorithm (try Google)
for this.

Another thing to look at is "par".
 
E

Ed Prochak

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);
}
/******************************************************************/
 
C

CBFalconer

can anyone point me to some piece of code that do text
justification of fixed fonts like those that nroff do on manpages?

The following simple program (a modification of my generalized
filter source) may be useful:

/* ----- justify.c -----
Filter text file, right justifying by inserting
spaces between words. Words are anything separated
by blanks, tabs, newlines, formfeeds, bell, etc.

The single (optional) parameter is the output line
length, and defaults to 65. Execution without any
input redirections causes a help message.

This is a quick and dirty utility.
Released to public domain 2003-01-28 by:
<mailto:[email protected]>
*/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define RHDEFAULT 65
#define RHMIN 20

static int rhcol; /* right hand column limit */
static int ragged; /* No rh justification, 0 init */

/* ------------------- */

/* This is very likely to be non-portable */
/* DOES NOT check fp open for reading */
/* NULL fp is considered a keyboard here! */
static int akeyboard(FILE *fp)
{
#ifndef __TURBOC__
# ifdef __STDC__
/* This dirty operation allows gcc -ansi -pedantic */
extern int fileno(FILE *fp);
extern int isatty(int fn);
# endif
#endif
return ((fp != NULL) && isatty(fileno(fp)));
} /* akeyboard */

/* ------------------- */

static void help(char *phrase1, char *phrase2)
{
if (phrase1) fprintf(stderr, "%s", phrase1);
if (phrase2) fprintf(stderr, "%s", phrase2);
fprintf(stderr, "\n"
"Usage: justify [rightmargin] <infile >outfile\n"
" The default rightmargin is 65\n"
" and values less than 20 are rejected\n"
"\n"
"A large value of rightmargin will effectively\n"
"convert all paragraphs into single lines\n"
"\n"
"A negative rightmargin causes ragged right\n"
"\n"
"A blank line delimits paragraphs\n");
} /* help */

/* ------------------- */

static int initialize(int argc, char *argv[])
{
long rightcol;
char *err;

if (akeyboard(stdin) || (argc > 2)) {
help(NULL, NULL);
return 0;
}
rhcol = RHDEFAULT;
if (2 == argc) {
rightcol = strtol(argv[1], &err, 10);
if (rightcol < 0) {
rightcol = -rightcol;
ragged = 1;
}
if ((err == argv[1]) || (rightcol < RHMIN)) {
help("Bad argument: ", argv[1]);
return 0;
}
else rhcol = rightcol;
}
return 1;
} /* initialize */

/* ------------------- */

static void cleanup(void)
{
} /* cleanup */

/* ------------------- */

/* ================================== */
/* Routines for text input and output */
/* ================================== */

static void skipblanks(FILE *f)
{
int ch;

while ( (' ' == (ch = getc(f))) || ('\t' == ch) ||
('\v' == ch) || ('\f' == ch) || ('\a' == ch) )
continue;
ungetc(ch, f);
} /* skipblanks */

/* ------------------- */

/* The file is assumed to hold no control chars */
/* other than \n \t \v \a and \f. A blank line */
/* marks a paragraph ending word */
static int nextword(FILE *f, char *buffer, int max)
{
int i, ch;

skipblanks(f);
if (EOF == (ch = getc(f))) return 0;

/* Detect paragraph endings as \n\n */
if ('\n' == ch) {
skipblanks(f); ch = getc(f);
if ('\n' == ch) { /* paragraph ending */
buffer[0] = buffer[1] = ch; /* wd = "\n\n" */
buffer[2] = '\0';
/* now we have to absorb any more blank lines */
do {
skipblanks(f); ch = getc(f);
} while ('\n' == ch);
ungetc(ch, f);
return 1;
}
}
/* now ch holds the first non-blank. Use all printable */
if (EOF == ch) return 0;
if (!isgraph(ch)) {
fprintf(stderr, "'%c', 0x%x WARN: Invalid character\n",
ch, (unsigned)ch);
}

i = 0;
do {
buffer[i++] = ch;
if (i >= max) { /* truncate over long words */
i--;
break; /* leaving ch for next word */
}
ch = getc(f);
} while (isgraph(ch));

ungetc(ch, f); /* save for next word, may be \n */
buffer = '\0'; /* terminate string */
return 1;
} /* nextword */

/* ------------------- */

static void justify(char *ln, int wdgaps, int xtra, FILE *out)
{
int insert, i;
static int oddln = 0; /* for rt left blank insertion */
char ch;

#ifdef DEBUG
fprintf(out, "%2d %2d ", wdgaps, xtra);
#endif
insert = 0; oddln = !oddln;
if (wdgaps)
while (xtra > wdgaps) {
insert++; xtra -= wdgaps;
}
while ((ch = *ln++)) {
putc(ch, out);
if (' ' == ch) {
if (xtra) {
xtra--;
putc(' ', out);
}
for (i = insert; i; i--) putc(' ', out);
}
}
putc('\n', out);
} /* justify */

/* ------------------- */

static int filter(FILE *in, FILE *out)
{
char *buf;
char *ln;
int wdcount, lnlgh, wdlgh;
char *eop = "\n\n"; /* end of paragraph */
int done, endpar;

if (!(buf = malloc(rhcol+1))) exit(EXIT_FAILURE);
if (!(ln = malloc(rhcol+1))) exit(EXIT_FAILURE);

done = !nextword(in, buf, rhcol + 1);
endpar = !strcmp(buf, eop);

while (!endpar && !done) {
/* form paragraph */
wdlgh = strlen(buf);
wdcount = 0;
*ln = '\0'; lnlgh = 0;

while ((((lnlgh + wdlgh) < rhcol) || !lnlgh)
&& !done && !endpar) {
/* form a line */
if (lnlgh) ln[lnlgh++] = ' ';
strcpy(ln + lnlgh, buf);
lnlgh += wdlgh;
wdcount++;

done = !nextword(in, buf, rhcol + 1);
endpar = !strcmp(buf, eop);
wdlgh = strlen(buf);
}

/* dump the line, wdcount words */
if (endpar || done) lnlgh = rhcol;
if (ragged) fprintf(out, "%s\n", ln);
else justify(ln, wdcount-1, rhcol-lnlgh, out);

if (endpar) {
fputc('\n', out);
done = !nextword(in, buf, rhcol + 1);
endpar = !strcmp(buf, eop);
}
}
return 0;
} /* filter */

/* ------------------- */

int main(int argc, char *argv[])
{
if (!initialize(argc, argv)) return EXIT_FAILURE;
else {
(void)filter(stdin, stdout);
cleanup();
}
return 0;
} /* main */
 
B

Ben Bacarisse

Well, the code for nroff should be easy enough to find (look for
groff, the most widely-used implementation).

But I recommend not justifying with fixed width fonts. It's much
harder to read.

If you really want to do it, you fill the line with as many words as
will fit, then distribute the required number of extra spaces in the
gaps. You might use a version of Bressenham's algorithm (try Google)
for this.

The next step in complexity is to apply a line-break algorithm to a
whole paragraph. It may sometimes be better to break early in order
to avoid a really bad break later. I don't know if groff does this
but TeX does something like this (though it has the option to overfill a
line also) and the algorithm is described in _The TeX Book_ by Knuth.
 
K

Keith Thompson

Ed Prochak said:
Hello,
can anyone point me to some piece of code that do text
justification of fixed fonts like those that nroff do on manpages?

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^)
[...]
#ifndef NULL
#define NULL ((char *)0)
#endif
[...]

Why do you do this rather than just ``#include <stddef.h>'' (or one of
the other standard headers that define NULL)?
 
K

Keith Thompson

Keith Thompson said:
Ed Prochak said:
Hello,
can anyone point me to some piece of code that do text
justification of fixed fonts like those that nroff do on manpages?

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^)
[...]
#ifndef NULL
#define NULL ((char *)0)
#endif
[...]

Why do you do this rather than just ``#include <stddef.h>'' (or one of
the other standard headers that define NULL)?

And as I realized just after I posted this, ``((char *)0)'' isn't even
a valid definition for NULL.

The language defines it for you. Just use it. And if you want to
define something else (say, something that's specifically of type
char*), give it a different name.
 
W

Wade Ward

clearly correct.

Sometimes the ISO soln is the best one.

--
South Jordan pkwy
435 -838-7760
President
(e-mail address removed)
Westates Companies
Merrill Jensen Consulting
1108 W. South Jordan pkwy
42
(e-mail address removed)


Merrill Jensen Consulting
1108 W. South Jordan pkwy
435 -838-7760
President
(e-mail address removed)
Westates Companies
1108 W. South Jordan pkwy
435 -838-7760
President
(e-mail address removed)

Keith Thompson said:
Keith Thompson said:
Ed Prochak said:
On Oct 23, 11:33 am, (e-mail address removed) wrote:
Hello,
can anyone point me to some piece of code that do text
justification of fixed fonts like those that nroff do on manpages?

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^)
[...]
#ifndef NULL
#define NULL ((char *)0)
#endif
[...]

Why do you do this rather than just ``#include <stddef.h>'' (or one of
the other standard headers that define NULL)?

And as I realized just after I posted this, ``((char *)0)'' isn't even
a valid definition for NULL.

The language defines it for you. Just use it. And if you want to
define something else (say, something that's specifically of type
char*), give it a different name.

--
Keith Thompson (The_Other_Keith) (e-mail address removed)
<http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*>
<http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
W

Wade Ward

Can you post more info on this book?

--
wade ward

Westates Companies
1108 W. South Jordan pkwy
435 -838-7760
President
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top