shithub: neatroff

Download patch

ref: 60965920e172133f0313482b7397435d2a8bd3a5
parent: 118adea928e25b13d9a0d294c8c3de908ba5dbd9
author: Ali Gholami Rudi <ali@rudi.ir>
date: Fri Mar 6 03:45:27 EST 2015

fmt: line break cost after a word with \j

--- a/fmt.c
+++ b/fmt.c
@@ -29,6 +29,7 @@
 	int gap;	/* the space before this word */
 	int hy;		/* hyphen width if inserted after this word */
 	int str;	/* does the space before it stretch */
+	int cost;	/* the extra cost of line break after this word */
 };
 
 struct line {
@@ -259,7 +260,7 @@
 }
 
 static void fmt_wb2word(struct fmt *f, struct word *word, struct wb *wb,
-			int hy, int str, int gap)
+			int hy, int str, int gap, int cost)
 {
 	int len = strlen(wb_buf(wb));
 	word->s = xmalloc(len + 1);
@@ -267,6 +268,7 @@
 	word->wid = wb_wid(wb);
 	word->elsn = wb->els_neg;
 	word->elsp = wb->els_pos;
+	word->cost = cost ? wb_cost(wb) : 0;
 	word->hy = hy ? wb_hywid(wb) : 0;
 	word->str = str;
 	word->gap = gap;
@@ -307,7 +309,7 @@
 	int cf, cs, cm;
 	n = fmt_hyphmarks(src, hyidx, hyins);
 	if (n <= 0) {
-		fmt_wb2word(f, &f->words[f->nwords++], wb, 0, 1, gap);
+		fmt_wb2word(f, &f->words[f->nwords++], wb, 0, 1, gap, 1);
 		return;
 	}
 	/* update f->fillreq considering the new sub-words */
@@ -319,7 +321,7 @@
 		end = src + (i < n ? hyidx[i] : strlen(src));
 		wb_catstr(&wbc, beg, end);
 		fmt_wb2word(f, &f->words[f->nwords++], &wbc,
-			i < n && hyins[i], i == 0, i == 0 ? gap : 0);
+			i < n && hyins[i], i == 0, i == 0 ? gap : 0, i == n);
 		/* restoring wbc */
 		wb_fnszget(&wbc, &cs, &cf, &cm);
 		wb_reset(&wbc);
@@ -416,7 +418,7 @@
 	if (pos <= 0)
 		return 0;
 	if (f->best_pos[pos] >= 0)
-		return f->best[pos];
+		return f->best[pos] + f->words[pos - 1].cost;
 	lwid = f->words[pos - 1].hy;	/* non-zero if the last word is hyphenated */
 	hyphenated = f->words[pos - 1].hy != 0;
 	i = pos - 1;
@@ -440,7 +442,7 @@
 		}
 		i--;
 	}
-	return f->best[pos];
+	return f->best[pos] + f->words[pos - 1].cost;
 }
 
 static int fmt_bestpos(struct fmt *f, int pos)
--- a/ren.c
+++ b/ren.c
@@ -646,6 +646,9 @@
 	case 'h':
 		wb_hmov(wb, eval(arg, 'm'));
 		break;
+	case 'j':
+		wb_setcost(wb, eval(arg, 0));
+		break;
 	case 'k':
 		num_set(map(arg), wb == cwb ? f_hpos() - n_lb : wb_wid(wb));
 		break;
@@ -735,7 +738,7 @@
 			wb_hmov(wb, w - wb_wid(wb));
 			return;
 		}
-		if (strchr(" bCcDdefHhkLlmNoprSsuvXxZz0^|!{}&/,", c[1])) {
+		if (strchr(" bCcDdefHhjkLlmNoprSsuvXxZz0^|!{}&/,", c[1])) {
 			arg[0] = '\0';
 			if (strchr(ESC_P, c[1]))
 				unquotednext(arg, c[1], next, back);
--- a/roff.h
+++ b/roff.h
@@ -57,7 +57,7 @@
 #define SC_EM		(n_s * SC_IN / 72)
 
 /* escape sequences */
-#define ESC_Q	"bCDhHlLNoRSvwxXZ?"	/* \X'ccc' quoted escape sequences */
+#define ESC_Q	"bCDhHjlLNoRSvwxXZ?"	/* \X'ccc' quoted escape sequences */
 #define ESC_P	"*fgkmns"		/* \Xc \X(cc \X[ccc] escape sequences */
 
 #define MIN(a, b)	((a) < (b) ? (a) : (b))
@@ -224,6 +224,7 @@
 	int f, s, m;		/* the last output font and size */
 	int r_f, r_s, r_m;	/* current font and size; use n_f and n_s if -1 */
 	int part;		/* partial input (\c) */
+	int cost;		/* the extra cost of line break after this word */
 	int els_neg, els_pos;	/* extra line spacing */
 	int h, v;		/* buffer vertical and horizontal positions */
 	int ct, sb, st;		/* \w registers */
@@ -246,6 +247,8 @@
 void wb_putexpand(struct wb *wb, char *c);
 int wb_part(struct wb *wb);
 void wb_setpart(struct wb *wb);
+int wb_cost(struct wb *wb);
+void wb_setcost(struct wb *wb, int cost);
 void wb_drawl(struct wb *wb, int c, int h, int v);
 void wb_drawc(struct wb *wb, int c, int r);
 void wb_drawe(struct wb *wb, int c, int h, int v);
--- a/wb.c
+++ b/wb.c
@@ -290,6 +290,16 @@
 	wb->part = 1;
 }
 
+int wb_cost(struct wb *wb)
+{
+	return wb->cost;
+}
+
+void wb_setcost(struct wb *wb, int cost)
+{
+	wb->cost = cost;
+}
+
 void wb_drawl(struct wb *wb, int c, int h, int v)
 {
 	wb_flush(wb);