ref: a174597fc92cb42492559805f1e3eb7d85939732
parent: 96f78282dd2aa43bb8cc038cf15cfdf20cd598b9
author: Ali Gholami Rudi <ali@rudi.ir>
date: Sun Dec 14 13:28:37 EST 2014
fmt: more penalty when hyphenating consecutive lines The .hycost request now takes three arguments: the second specifies the additional cost of two consecutive hyphenated lines and the third does so for three consecutive hyphenated lines.
--- a/fmt.c
+++ b/fmt.c
@@ -384,10 +384,20 @@
return ratio * ratio / 100l * (nspc ? nspc : 1);
}
+/* the number of hyphenations in consecutive lines ending at pos (2 at most) */
+static int fmt_hydepth(struct fmt *f, int pos)
+{
+ int n = 0;
+ while (pos > 0 && f->words[pos - 1].hy && ++n < 2)
+ pos = f->best_pos[pos];
+ return n;
+}
+
/* the cost of putting a line break before word pos */
static long fmt_findcost(struct fmt *f, int pos)
{
- int i, pen = 0;
+ int hycost[] = {0, n_hycost2, n_hycost2 + n_hycost3};
+ int i, hyphenated;
long cur;
int llen = MAX(1, FMT_LLEN(f));
int lwid = 0; /* current line length */
@@ -397,12 +407,9 @@
return 0;
if (f->best_pos[pos] >= 0)
return f->best[pos];
+ lwid = f->words[pos - 1].hy; /* non-zero if the last word is hyphenated */
+ hyphenated = f->words[pos - 1].hy != 0;
i = pos - 1;
- lwid = 0;
- if (f->words[i].hy) /* the last word is hyphenated */
- lwid += f->words[i].hy;
- if (f->words[i].hy)
- pen = n_hycost;
while (i >= 0) {
lwid += f->words[i].wid;
if (i + 1 < pos)
@@ -414,8 +421,9 @@
if (lwid - (swid * n_ssh / 100) > llen)
if (pos - i > 1)
break;
- cur = fmt_findcost(f, i) + FMT_COST(llen, lwid, swid, nspc) +
- pen * (nspc ? nspc : 1);
+ cur = fmt_findcost(f, i) + FMT_COST(llen, lwid, swid, nspc);
+ if (hyphenated)
+ cur += n_hycost + hycost[fmt_hydepth(f, i)];
if (f->best_pos[pos] < 0 || cur < f->best[pos]) {
f->best_pos[pos] = i;
f->best_dep[pos] = f->best_dep[i] + 1;
--- a/reg.c
+++ b/reg.c
@@ -37,7 +37,7 @@
".L", ".nI", ".nm", ".nM", ".nn",
".nS", ".m", ".s", ".u", ".v",
".it", ".itn", ".mc", ".mcn",
- ".ce", ".f0", ".hy", ".hycost", ".i0", ".l0",
+ ".ce", ".f0", ".hy", ".hycost", ".hycost2",".hycost3", ".i0", ".l0",
".L0", ".m0", ".n0", ".s0", ".ss", ".ssh", ".sss", ".pmll", ".pmllcost",
".ti", ".lt", ".lt0", ".v0",
};
--- a/roff.h
+++ b/roff.h
@@ -465,6 +465,8 @@
#define n_lg (*nreg(map(".lg"))) /* .lg mode */
#define n_hy (*nreg(map(".hy"))) /* .hy mode */
#define n_hycost (*nreg(map(".hycost"))) /* hyphenation cost */
+#define n_hycost2 (*nreg(map(".hycost2"))) /* hyphenation cost #2 */
+#define n_hycost3 (*nreg(map(".hycost3"))) /* hyphenation cost #3 */
#define n_i0 (*nreg(map(".i0"))) /* last .i */
#define n_ti (*nreg(map(".ti"))) /* pending .ti */
#define n_kn (*nreg(map(".kn"))) /* .kn mode */
--- a/tr.c
+++ b/tr.c
@@ -462,6 +462,8 @@
static void tr_hycost(char **args)
{
n_hycost = args[1] ? eval_re(args[1], n_hycost, '\0') : 0;
+ n_hycost2 = args[2] ? eval_re(args[2], n_hycost2, '\0') : 0;
+ n_hycost3 = args[3] ? eval_re(args[3], n_hycost3, '\0') : 0;
}
static void tr_hydash(char **args)