shithub: neatroff

Download patch

ref: 3510cb585c3efa876a78add5a42bf9c06f186b1f
parent: 08d6e9ceb2d7d420be1d916d32faeda18c4f27e0
author: Ali Gholami Rudi <ali@rudi.ir>
date: Sat Dec 15 15:45:02 EST 2018

fmt: format a single line if line settings change

Reported by Pierre-Jean Fichet <pierrejean.fichet@posteo.net>.

--- a/fmt.c
+++ b/fmt.c
@@ -582,7 +582,7 @@
 }
 
 /* extract the first nreq formatted lines before the word at pos */
-static int fmt_head(struct fmt *f, int nreq, int pos)
+static int fmt_head(struct fmt *f, int nreq, int pos, int nohy)
 {
 	int best = pos;		/* best line break for nreq-th line */
 	int prev, next;		/* best line breaks without hyphenation */
@@ -593,6 +593,8 @@
 		best = fmt_bestpos(f, best);
 	prev = best;
 	next = best;
+	if (!nohy)
+		return best;
 	/* finding closest line breaks without hyphenation */
 	while (prev > 1 && f->words[prev - 1].hy &&
 			fmt_bestdep(f, prev - 1) == nreq)
@@ -648,7 +650,12 @@
 	/* not enough words to fill */
 	if ((f->fillreq <= 0 || f->words_n < f->fillreq) && llen <= FMT_LLEN(f))
 		return 0;
-	nreq = (n_hy & HY_LAST) ? fmt_safelines() : 0;
+	/* lines until a trap or page end */
+	nreq = fmt_safelines();
+	/* if line settings are changed, output a single line */
+	if (fmt_confchanged(f))
+		nreq = 1;
+	/* enough lines are collected already */
 	if (nreq > 0 && nreq <= fmt_nlines(f))
 		return 1;
 	/* resetting positions */
@@ -661,7 +668,10 @@
 		f->best_pos[i] = -1;
 	end = fmt_breakparagraph(f, f->words_n, br);
 	if (nreq > 0) {
-		end_head = fmt_head(f, nreq - fmt_nlines(f), end);
+		int nohy = 0;	/* do not hyphenate the last line */
+		if (n_hy & HY_LAST && nreq == fmt_nlines(f))
+			nohy = 1;
+		end_head = fmt_head(f, nreq - fmt_nlines(f), end, nohy);
 		head = end_head < end;
 		end = end_head;
 	}