Don't format lines that look like troff requests, for

compatibility with old fmt(1).  New option -n permits
formatting of lines beginning with a dot character.

PR:		bin/31392
MFC after:	3 days
This commit is contained in:
Ruslan Ermilov 2002-01-11 19:06:48 +00:00
parent b9c35b6942
commit deba245176
2 changed files with 28 additions and 5 deletions

View File

@ -42,7 +42,7 @@
.Nd simple text formatter
.Sh SYNOPSIS
.Nm fmt
.Op Fl cmps
.Op Fl cmnps
.Op Fl d Ar chars
.Op Fl l Ar num
.Op Fl t Ar num
@ -88,6 +88,14 @@ In this case, most of the other
options are ignored; no splitting or joining of lines is done.
.It Fl m
Try to format mail header lines contained in the input sensibly.
.It Fl n
Format lines beginning with a
.Ql \&.
(dot) character.
Normally,
.Nm
does not fill these lines, for compatibility with
.Xr nroff 1 .
.It Fl p
Allow indented paragraphs.
Without the

View File

@ -30,6 +30,8 @@
* preceded by a non-blank non-message-header line, is
* taken to start a new paragraph, which also contains
* any subsequent lines with non-empty leading whitespace.
* Unless the `-n' option is given, lines beginning with
* a . (dot) are not formatted.
* 3. The "everything else" is split into words; a word
* includes its trailing whitespace, and a word at the
* end of a line is deemed to be followed by a single
@ -222,6 +224,7 @@ static int tab_width=8; /* Number of spaces per tab stop */
static size_t output_tab_width=8; /* Ditto, when squashing leading spaces */
static const char *sentence_enders=".?!"; /* Double-space after these */
static int grok_mail_headers=0; /* treat embedded mail headers magically? */
static int format_troff=0; /* Format troff? */
static int n_errors=0; /* Number of failed files. Return on exit. */
static char *output_buffer=0; /* Output line will be built here */
@ -257,10 +260,11 @@ main(int argc, char *argv[]) {
/* 1. Grok parameters. */
while ((ch = getopt(argc, argv, "0123456789cd:hl:mpst:w:")) != -1)
while ((ch = getopt(argc, argv, "0123456789cd:hl:mnpst:w:")) != -1)
switch(ch) {
case 'c':
centerP = 1;
format_troff = 1;
continue;
case 'd':
sentence_enders = optarg;
@ -272,6 +276,9 @@ main(int argc, char *argv[]) {
case 'm':
grok_mail_headers = 1;
continue;
case 'n':
format_troff = 1;
continue;
case 'p':
allow_indented_paragraphs = 1;
continue;
@ -307,6 +314,7 @@ main(int argc, char *argv[]) {
" -d <chars> double-space after <chars> at line end\n"
" -l <n> turn each <n> spaces at start of line into a tab\n"
" -m try to make sure mail header lines stay separate\n"
" -n format lines beginning with a dot\n"
" -p allow indented paragraphs\n"
" -s coalesce whitespace inside lines\n"
" -t <n> have tabs every <n> columns\n"
@ -395,6 +403,7 @@ process_stream(FILE *stream, const char *name) {
}
/* We need a new paragraph if and only if:
* this line is blank,
* OR it's a troff request (and we don't format troff),
* OR it's a mail header,
* OR it's not a mail header AND the last line was one,
* OR the indentation has changed
@ -402,6 +411,7 @@ process_stream(FILE *stream, const char *name) {
* AND this isn't the second line of an indented paragraph.
*/
if ( length==0
|| (line[0]=='.' && !format_troff)
|| header_type==hdr_Header
|| (header_type==hdr_NonHeader && prev_header_type>hdr_NonHeader)
|| (np!=last_indent
@ -412,8 +422,11 @@ process_stream(FILE *stream, const char *name) {
first_indent = np;
last_indent = np;
if (header_type==hdr_Header) last_indent=2; /* for cont. lines */
if (length==0) {
putchar('\n');
if (length==0 || (line[0]=='.' && !format_troff)) {
if (length==0)
putchar('\n');
else
printf("%.*s\n", (int)length, line);
prev_header_type=hdr_ParagraphStart;
continue;
}
@ -594,11 +607,13 @@ get_line(FILE *stream, size_t *lengthp) {
size_t len=0;
int ch;
size_t spaces_pending=0;
int troff=0;
if (buf==NULL) { length=100; buf=XMALLOC(length); }
while ((ch=getc(stream)) != '\n' && ch != EOF) {
if (len+spaces_pending==0 && ch=='.' && !format_troff) troff=1;
if (ch==' ') ++spaces_pending;
else if (isprint(ch)) {
else if (troff || isprint(ch)) {
while (len+spaces_pending >= length) {
length*=2; buf=xrealloc(buf, length);
}