shithub: neatroff

Download patch

ref: 57cbedc36926da8a101bbb7bd3a6dd119c3ebc17
parent: 52bd1c9b13849dd92d9e3619bcf0a89d4067f849
author: Ali Gholami Rudi <ali@rudi.ir>
date: Wed Nov 21 18:49:11 EST 2012

ren: adjust lines

--- a/ren.c
+++ b/ren.c
@@ -17,6 +17,8 @@
 static int nwords;
 static int wid;				/* total width of the buffer */
 static int ren_backed = -1;		/* pushed back character */
+static int req_br;			/* pending .br request */
+static int req_sp;			/* pending .sp request */
 
 static int ren_next(void)
 {
@@ -44,22 +46,16 @@
 	return l;
 }
 
-static void down(int n)
+static void adjust(char *s, int adj)
 {
-	printf("v%d\n", n);
-}
-
-static void adjust(char *s)
-{
 	struct word *last = words;
 	struct word *cur;
 	int w = 0;
 	int lendiff;
 	int i;
-	if (!nwords) {
-		s[0] = '\0';
-		return;
-	}
+	int adj_div = 0;
+	int adj_rem = 0;
+	int n;
 	while (last < words + nwords && w + last->wid + last->blanks <= n_l) {
 		w += last->wid + last->blanks;
 		last++;
@@ -66,6 +62,13 @@
 	}
 	if (last > words)
 		last--;
+	n = last - words + 1;
+	if (adj && n > 1) {
+		adj_div = (n_l - w) / (n - 1);
+		adj_rem = n_l - w - adj_div * (n - 1);
+	}
+	for (i = 0; i < n - 1; i++)
+		words[i + 1].blanks += adj_div + (i < adj_rem);
 	for (cur = words; cur <= last; cur++) {
 		if (cur > words)
 			s += sprintf(s, "\\h'%du'", cur->blanks);
@@ -73,10 +76,10 @@
 		s += cur->end - cur->beg;
 	}
 	*s = '\0';
-	lendiff = last + 1 < words + nwords ? last[1].beg : buflen;
+	lendiff = n < nwords ? last[1].beg : buflen;
 	memmove(buf, buf + lendiff, buflen - lendiff);
 	buflen -= lendiff;
-	nwords -= last - words + 1;
+	nwords -= n;
 	memmove(words, last + 1, nwords * sizeof(words[0]));
 	wid -= w;
 	for (i = 0; i < nwords; i++) {
@@ -90,12 +93,7 @@
 
 void tr_br(int argc, char **args)
 {
-	char out[LINELEN];
-	buf[buflen] = '\0';
-	if (buflen) {
-		adjust(out);
-		out_put(out);
-	}
+	req_br = 1;
 }
 
 void tr_sp(int argc, char **args)
@@ -102,7 +100,7 @@
 {
 	tr_br(0, NULL);
 	if (argc > 1)
-		down(tr_int(args[1], 0, 'v'));
+		req_sp = tr_int(args[1], 0, 'v');
 }
 
 static void ren_ps(char *s)
@@ -176,6 +174,20 @@
 	*s = '\0';
 }
 
+static void ren_br(int adj)
+{
+	char out[LINELEN];
+	buf[buflen] = '\0';
+	if (buflen) {
+		adjust(out, adj);
+		out_put(out);
+	}
+	if (req_sp)
+		printf("v%d\n", req_sp);
+	req_br = 0;
+	req_sp = 0;
+}
+
 void render(void)
 {
 	char c[LLEN];
@@ -191,8 +203,8 @@
 	tr_br(0, NULL);
 	while (nextchar(c) > 0) {
 		g = NULL;
-		if (!word && wid > n_l)
-			tr_br(0, NULL);
+		if (!word && (wid > n_l || req_br))
+			ren_br(wid > n_l ? n_ad : 0);
 		if (c[0] == ' ' || c[0] == '\n') {
 			if (word) {
 				word->end = buflen;
@@ -250,5 +262,6 @@
 		word->wid += g_wid;
 		wid += g_wid;
 	}
-	tr_br(0, NULL);
+	ren_br(wid > n_l ? n_ad : 0);
+	ren_br(0);
 }
--- a/tr.c
+++ b/tr.c
@@ -94,6 +94,11 @@
 		n_i = tr_int(args[1], n_i, 'm');
 }
 
+static void tr_na(int argc, char **args)
+{
+	n_ad = 0;
+}
+
 static void tr_readcmd(char *s)
 {
 	int i = 0;
@@ -139,12 +144,13 @@
 	{"br", tr_br},
 	{"fp", tr_fp},
 	{"ft", tr_ft},
+	{"in", tr_in},
+	{"ll", tr_ll},
+	{"na", tr_na},
 	{"nr", tr_nr},
 	{"ps", tr_ps},
 	{"sp", tr_sp},
 	{"vs", tr_vs},
-	{"ll", tr_ll},
-	{"in", tr_in},
 };
 
 int tr_next(void)
--- a/xroff.c
+++ b/xroff.c
@@ -13,6 +13,7 @@
 	n_v = 12 * SC_PT;
 	n_s0 = n_s;
 	n_f0 = n_f;
+	n_ad = 1;
 }
 
 static void compile(void)
--- a/xroff.h
+++ b/xroff.h
@@ -25,6 +25,7 @@
 #define n_i		nreg[N_ID('.', 'i')]
 #define n_f0		nreg[N_ID('\0', 'f')]	/* last font */
 #define n_s0		nreg[N_ID('\0', 's')]	/* last size */
+#define n_ad		nreg[N_ID('\0', 'a')]	/* adjustment */
 
 /* device related variables */
 extern int dev_res;