/***************************************************************
*
* A crude text formatter.
*
* Formats the text read from stdin to fit within the
* line length M and writes it to stdout.
*
* This formatter makes several dubious assumptions:
*
* 1. Paragraphs are separated by blank lines.
* 2. The space and newline characters are the only
* characters that aren't part of a word.
* 3. No paragraph is more than BUFSIZE characters long.
* 4. No word is longer than the line length M.
*
**************************************************************/
#include <stdio.h>
#include "linebreaks.h"
int M = 50; /* Maximum length of a formatted line. */
#define BUFSIZE 10000
#define MAXWORDS 5000
char paragraphBuffer[BUFSIZE];
int paragraphIndex; /* active length of paragraphBuffer */
int paragraphWords; /* active length of paragraphWordLengths */
int paragraphWordLengths[MAXWORDS];
int paragraphLineBreaks[MAXWORDS];
int peekchar();
void FlushWhitespace();
int EndOfParagraph();
void ReadWord();
void ReadParagraph();
void FormatParagraph(int);
void WriteParagraph();
main() {
FlushWhitespace();
while (peekchar() != EOF) {
ReadParagraph();
FormatParagraph(M);
WriteParagraph();
printf ("\n\n");
}
}
int peekchar() {
int c = getchar();
ungetc(c, stdin);
return c;
}
void FlushWhitespace() {
int c = peekchar();
while ((c != EOF) && ((c == ' ') || (c == '\n'))) {
getchar();
c = peekchar();
}
}
/* Paragraphs. */
int EndOfParagraph() {
int c = peekchar();
while ((c == ' ') || (c == '\n')) {
if (c == ' ') {
getchar();
c = peekchar();
}
else {
getchar();
c = peekchar();
if ((c == EOF) || (c == '\n'))
return 1;
else;
}
}
return c == EOF;
}
void ReadWord() {
int c = peekchar();
while ((c != EOF) && (c != ' ') && (c != '\n')) {
paragraphBuffer [paragraphIndex] = c;
paragraphIndex = paragraphIndex + 1;
getchar();
c = peekchar();
}
paragraphBuffer [paragraphIndex] = ' ';
paragraphIndex = paragraphIndex + 1;
paragraphWords = paragraphWords + 1;
}
void ReadParagraph() {
paragraphIndex = 0;
paragraphWords = 0;
while (! EndOfParagraph())
ReadWord();
}
void FormatParagraph(int M) {
int i = 0;
int thisword = 0;
int index = 0;
/* Compute word lengths. */
while (index < paragraphIndex) {
if (paragraphBuffer [index] == ' ') {
paragraphWordLengths [i] = thisword;
i = i + 1;
thisword = 0;
index = index + 1;
}
else {
thisword = thisword + 1;
index = index + 1;
}
}
paragraphIndex = paragraphIndex - 1;
/* Choose line breaks. */
ChooseLineBreaks (paragraphWords,
paragraphWordLengths,
M,
paragraphLineBreaks);
/* Replace the chosen spaces by newlines. */
for (index = -1, i = 0;
i < paragraphWords;
index = index + 1 + paragraphWordLengths [i], i = i + 1) {
if (paragraphLineBreaks [i])
paragraphBuffer [index + 1 + paragraphWordLengths [i]] = '\n';
}
}
void WriteParagraph() {
int index;
for (index = 0; index < paragraphIndex; index = index + 1) {
putchar (paragraphBuffer [index]);
}
}