shithub: neatroff

Download patch

ref: 5ff8ac2dfe6acb3c27d22b0bc344bad06919d919
parent: 26222f68db3dcfc575e31c3a977e0e736438965c
author: Ali Gholami Rudi <ali@rudi.ir>
date: Fri Dec 12 11:16:07 EST 2014

fmt: specify the cost of short lines

Now the cost of short lines is 100 or the value specified as the
second argument of .pmll.

--- a/fmt.c
+++ b/fmt.c
@@ -173,7 +173,7 @@
 	return l;
 }
 
-static int fmt_extractline(struct fmt *f, int beg, int end, int llen, int spread)
+static int fmt_extractline(struct fmt *f, int beg, int end, int llen)
 {
 	int fmt_div, fmt_rem;
 	int w, i, nspc;
@@ -183,7 +183,7 @@
 	w = fmt_wordslen(f, beg, end);
 	nspc = fmt_spaces(f, beg, end);
 	/* stretch if (spread & 1) and shrink if (spread & 2) */
-	if (nspc && ((spread & 1 && w < llen) || (spread & 2 && w > llen))) {
+	if (nspc && llen) {
 		fmt_div = (llen - w) / nspc;
 		fmt_rem = (llen - w) % nspc;
 		if (fmt_rem < 0) {
@@ -202,8 +202,7 @@
 {
 	if (fmt_fillwords(f, 1))
 		return 1;
-	if (fmt_extractline(f, 0, f->nwords, FMT_LLEN(f) * n_pmll / 100,
-			FMT_ADJ(f) && n_j & AD_P))
+	if (fmt_extractline(f, 0, f->nwords, 0))
 		return 1;
 	f->filled = 0;
 	f->nls--;
@@ -385,14 +384,6 @@
 	return ratio * ratio / 100l * (nspc ? nspc : 1);
 }
 
-/* the cost of formatting last lines; should prevent widows */
-static long FMT_LCOST(int llen, int lwid, int swid, int nspc)
-{
-	if (!n_pmll || lwid >= llen * n_pmll / 100)
-		return 0;
-	return FMT_COST(llen * n_pmll / 100, lwid, swid, nspc);
-}
-
 /* the cost of putting a line break before word pos */
 static long fmt_findcost(struct fmt *f, int pos)
 {
@@ -411,7 +402,7 @@
 	if (f->words[i].hy)	/* the last word is hyphenated */
 		lwid += f->words[i].hy;
 	if (f->words[i].hy)
-		pen = n_hyp;
+		pen = n_hycost;
 	while (i >= 0) {
 		lwid += f->words[i].wid;
 		if (i + 1 < pos)
@@ -479,8 +470,10 @@
 		}
 		if (lwid > llen && i + 1 < pos)
 			break;
-		cost = fmt_findcost(f, i) +
-			(br ? FMT_LCOST(llen, lwid, swid, nspc) : 0);
+		cost = fmt_findcost(f, i);
+		/* the cost of formatting short lines; should prevent widows */
+		if (br && n_pmll && lwid < llen * n_pmll / 100)
+			cost += n_pmllcost;
 		if (best < 0 || cost < best_cost) {
 			best = i;
 			best_cost = cost;
@@ -527,7 +520,7 @@
 	if (beg > 0)
 		ret += fmt_break(f, beg);
 	f->words[beg].gap = 0;
-	if (fmt_extractline(f, beg, end, FMT_LLEN(f), FMT_ADJ(f) ? 3 : 0))
+	if (fmt_extractline(f, beg, end, FMT_ADJ(f) ? FMT_LLEN(f) : 0))
 		return ret;
 	if (beg > 0)
 		fmt_confupdate(f);
--- a/reg.c
+++ b/reg.c
@@ -37,8 +37,8 @@
 	".L", ".nI", ".nm", ".nM", ".nn",
 	".nS", ".m", ".s", ".u", ".v",
 	".it", ".itn", ".mc", ".mcn",
-	".ce", ".f0", ".hy", ".hyp", ".i0", ".l0",
-	".L0", ".m0", ".n0", ".s0", ".ss", ".ssh", ".sss", ".pmll",
+	".ce", ".f0", ".hy", ".hycost", ".i0", ".l0",
+	".L0", ".m0", ".n0", ".s0", ".ss", ".ssh", ".sss", ".pmll", ".pmllcost",
 	".ti", ".lt", ".lt0", ".v0",
 };
 
--- a/roff.h
+++ b/roff.h
@@ -463,7 +463,7 @@
 #define n_f0		(*nreg(map(".f0")))	/* last .f */
 #define n_lg		(*nreg(map(".lg")))	/* .lg mode */
 #define n_hy		(*nreg(map(".hy")))	/* .hy mode */
-#define n_hyp		(*nreg(map(".hyp")))	/* hyphenation penalty  */
+#define n_hycost	(*nreg(map(".hycost")))	/* hyphenation cost */
 #define n_i0		(*nreg(map(".i0")))	/* last .i */
 #define n_ti		(*nreg(map(".ti")))	/* pending .ti */
 #define n_kn		(*nreg(map(".kn")))	/* .kn mode */
@@ -474,7 +474,8 @@
 #define n_na		(*nreg(map(".na")))	/* .na mode */
 #define n_ns		(*nreg(map(".ns")))	/* .ns mode */
 #define n_o0		(*nreg(map(".o0")))	/* last .o */
-#define n_pmll		(*nreg(map(".pmll")))	/* minimum last line (.pmll) */
+#define n_pmll		(*nreg(map(".pmll")))	/* minimum line length (.pmll) */
+#define n_pmllcost	(*nreg(map(".pmllcost")))	/* short line cost */
 #define n_ss		(*nreg(map(".ss")))	/* word space (.ss) */
 #define n_sss		(*nreg(map(".sss")))	/* sentence space (.ss) */
 #define n_ssh		(*nreg(map(".ssh")))	/* word space compression (.ssh) */
--- a/tr.c
+++ b/tr.c
@@ -455,12 +455,13 @@
 
 static void tr_hyp(char **args)
 {
-	n_hyp = args[1] ? atoi(args[1]) : 0;
+	n_hycost = args[1] ? atoi(args[1]) : 0;
 }
 
 static void tr_pmll(char **args)
 {
 	n_pmll = args[1] ? atoi(args[1]) : 0;
+	n_pmllcost = args[2] ? atoi(args[2]) : 100;
 }
 
 static void tr_lg(char **args)