shithub: neatroff

Download patch

ref: 0b23d0b4a41bedb9d9b00bcef9c0b6414c4ef287
parent: 34ea5f4e771ff8af2f82f5683df3a9f47456751a
author: Ali Gholami Rudi <ali@rudi.ir>
date: Thu Mar 28 12:46:45 EDT 2013

ren: diversion dl and dn registers

--- a/adj.c
+++ b/adj.c
@@ -53,7 +53,7 @@
 }
 
 /* move n words from the adjustment buffer to s */
-static void adj_move(struct adj *a, int n, char *s)
+static int adj_move(struct adj *a, int n, char *s)
 {
 	struct word *cur;
 	int lendiff;
@@ -68,7 +68,7 @@
 	}
 	*s = '\0';
 	if (!n)
-		return;
+		return 0;
 	lendiff = n < a->nwords ? a->words[n].beg : a->len;
 	memmove(a->buf, a->buf + lendiff, a->len - lendiff + 1);
 	a->len -= lendiff;
@@ -79,10 +79,11 @@
 		a->words[i].beg -= lendiff;
 		a->words[i].end -= lendiff;
 	}
+	return w;
 }
 
 /* fill and copy a line into s */
-void adj_fill(struct adj *a, int mode, int ll, char *s)
+int adj_fill(struct adj *a, int mode, int ll, char *s)
 {
 	int adj_div, adj_rem;
 	int w = 0;
@@ -89,8 +90,7 @@
 	int i, n;
 	if (mode == ADJ_N || adj_fullnf(a)) {
 		a->nls--;
-		adj_move(a, a->nwords, s);
-		return;
+		return adj_move(a, a->nwords, s);
 	}
 	for (n = 0; n < a->nwords; n++) {
 		if (n && w + a->words[n].wid + a->words[n].gap > ll)
@@ -104,10 +104,11 @@
 		for (i = 0; i < n - 1; i++)
 			a->words[i + 1].gap += adj_div + (i < adj_rem);
 	}
-	adj_move(a, n, s);
+	w = adj_move(a, n, s);
 	if (a->nwords)
 		a->wid -= a->words[0].gap;
 	a->words[0].gap = 0;
+	return w;
 }
 
 static void adj_wordbeg(struct adj *adj, int gap)
--- a/ren.c
+++ b/ren.c
@@ -12,6 +12,8 @@
 struct div {
 	struct sbuf sbuf;	/* diversion output */
 	int reg;		/* diversion register */
+	int dl;			/* diversion width */
+	int prev_d;		/* previous \(.d value */
 };
 static struct div divs[NPREV];	/* diversion stack */
 static struct div *cdiv;	/* current diversion */
@@ -56,6 +58,8 @@
 		cdiv = cdiv ? cdiv + 1 : divs;
 		sbuf_init(&cdiv->sbuf);
 		cdiv->reg = REG(args[1][0], args[1][1]);
+		cdiv->dl = 0;
+		cdiv->prev_d = n_d;
 		if (args[0][2] == 'a' && str_get(cdiv->reg))	/* .da */
 			sbuf_append(&cdiv->sbuf, str_get(cdiv->reg));
 		n_d = 0;
@@ -63,6 +67,9 @@
 		sbuf_putnl(&cdiv->sbuf);
 		str_set(cdiv->reg, sbuf_buf(&cdiv->sbuf));
 		sbuf_done(&cdiv->sbuf);
+		n_dl = cdiv->dl;
+		n_dn = n_d;
+		n_d = cdiv->prev_d;
 		cdiv = cdiv > divs ? cdiv - 1 : NULL;
 	}
 }
@@ -71,25 +78,27 @@
 static void down(int n)
 {
 	char cmd[32];
-	n_d += n;
+	n_d += n ? n : n_v;
 	if (cdiv) {
 		sbuf_putnl(&cdiv->sbuf);
 		sprintf(cmd, ".sp %du\n", n);
-		sbuf_append(&cdiv->sbuf, cmd);
+		if (n)
+			sbuf_append(&cdiv->sbuf, cmd);
 	} else {
 		n_nl = n_d;
 		if (n_nl <= n_p)
-			OUT("v%d\n", n);
+			OUT("v%d\n", n ? n : n_v);
 	}
 	ren_ne(0);
 }
 
-static void out_line(char *out)
+static void out_line(char *out, int w)
 {
 	char cmd[32];
+	down(0);
 	if (cdiv) {
-		if (!sbuf_empty(&cdiv->sbuf))
-			down(n_v);
+		if (cdiv->dl < w)
+			cdiv->dl = w;
 		sprintf(cmd, "\\h'%d'", n_i);
 		sbuf_append(&cdiv->sbuf, DIV_BEG);
 		sbuf_append(&cdiv->sbuf, cmd);
@@ -96,7 +105,6 @@
 		sbuf_append(&cdiv->sbuf, out);
 		sbuf_append(&cdiv->sbuf, DIV_END);
 	} else {
-		down(n_v);
 		OUT("H%d\n", n_o + n_i);
 		output(out);
 	}
@@ -105,10 +113,11 @@
 static void ren_br(int sp, int force)
 {
 	char out[LNLEN];
+	int w;
 	if (!adj_empty(adj, ADJ_MODE)) {
-		adj_fill(adj, force ? ADJ_N : ADJ_MODE, ADJ_LL, out);
+		w = adj_fill(adj, force ? ADJ_N : ADJ_MODE, ADJ_LL, out);
 		ren_ne(n_v);
-		out_line(out);
+		out_line(out, w);
 		ren_ne(n_v);
 	}
 	if (sp)
--- a/xroff.h
+++ b/xroff.h
@@ -147,7 +147,7 @@
 
 struct adj *adj_alloc(void);
 void adj_free(struct adj *adj);
-void adj_fill(struct adj *adj, int mode, int linelen, char *dst);
+int adj_fill(struct adj *adj, int mode, int linelen, char *dst);
 void adj_put(struct adj *adj, int wid, char *s, ...);
 void adj_swid(struct adj *adj, int swid);
 int adj_full(struct adj *adj, int mode, int linelen);
@@ -165,6 +165,8 @@
 #define n_s		(*nreg(REG('.', 's')))
 #define n_u		(*nreg(REG('.', 'u')))
 #define n_v		(*nreg(REG('.', 'v')))
+#define n_dl		(*nreg(REG('d', 'l')))
+#define n_dn		(*nreg(REG('d', 'n')))
 #define n_nl		(*nreg(REG('n', 'l')))
 #define n_pg		(*nreg(REG('%', '\0')))	/* % */
 #define n_f0		(*nreg(REG(0, 'f')))	/* last font */