shithub: neatroff

Download patch

ref: 08b6db376a3ed78a46af972ca853256160dddbab
parent: b6fac629b65e7769dfaf2b9252221e99cd4568dc
author: Ali Gholami Rudi <ali@rudi.ir>
date: Tue Apr 16 17:09:49 EDT 2013

adj: delay the effect of .in, .ll, and .ti for partial lines

--- a/adj.c
+++ b/adj.c
@@ -4,6 +4,8 @@
 #include <string.h>
 #include "xroff.h"
 
+#define ADJ_LL(a)	((a)->ll > (a)->li + (a)->lt ? (a)->ll - (a)->li - (a)->lt : 0)
+
 struct word {
 	int beg;	/* word beginning offset */
 	int end;	/* word ending offset */
@@ -21,8 +23,41 @@
 	int swid;			/* current space width */
 	int gap;			/* space before the next word */
 	int nls;			/* newlines before the next word */
+	int l, i, t;			/* current .l, .i and ti */
+	int ll, li, lt;			/* current line's .l, .i and ti */
 };
 
+void adj_ll(struct adj *adj, int ll)
+{
+	adj->l = ll;
+}
+
+void adj_ti(struct adj *adj, int ti)
+{
+	adj->t = ti;
+}
+
+void adj_in(struct adj *adj, int in)
+{
+	adj->i = in;
+}
+
+void adj_conf(struct adj *adj, int *ll, int *in, int *ti)
+{
+	*ll = adj->ll;
+	*in = adj->li;
+	*ti = adj->lt;
+}
+
+/* .ll, .in and .ti are delayed until the partial line is output */
+static void adj_confupdate(struct adj *adj)
+{
+	adj->ll = adj->l;
+	adj->li = adj->i;
+	adj->lt = adj->t;
+	adj->t = 0;
+}
+
 /* does the adjustment buffer need to be flushed without filling? */
 static int adj_fullnf(struct adj *a)
 {
@@ -31,13 +66,13 @@
 }
 
 /* does the adjustment buffer need to be flushed? */
-int adj_full(struct adj *a, int linelen)
+int adj_full(struct adj *a, int fill)
 {
-	if (!linelen)
+	if (!fill)
 		return a->nls;
 	if (adj_fullnf(a))
 		return 1;
-	return !a->word && a->wid > linelen;
+	return !a->word && a->wid > ADJ_LL(a);
 }
 
 /* is the adjustment buffer empty? */
@@ -79,16 +114,19 @@
 		a->words[i].beg -= lendiff;
 		a->words[i].end -= lendiff;
 	}
+	if (a->nwords)		/* apply the new .l and .i */
+		adj_confupdate(a);
 	return w;
 }
 
 /* fill and copy a line into s */
-int adj_fill(struct adj *a, int ad_b, int ll, char *s)
+int adj_fill(struct adj *a, int ad_b, int fill, char *s)
 {
 	int adj_div, adj_rem;
 	int w = 0;
 	int i, n;
-	if (!ll || adj_fullnf(a)) {
+	int ll = ADJ_LL(a);
+	if (!fill || adj_fullnf(a)) {
 		a->nls--;
 		return adj_move(a, a->nwords, s);
 	}
@@ -144,6 +182,8 @@
 		adj->swid = wid;
 		return;
 	}
+	if (!adj->nwords)	/* apply the new .l and .i */
+		adj_confupdate(adj);
 	if (!adj->word) {
 		if (adj->nls && !adj->gap && adj->nwords >= 1)
 			adj->gap = adj->swid;
--- a/reg.c
+++ b/reg.c
@@ -33,7 +33,6 @@
 	REG(0, 'l'),
 	REG(0, 'n'),
 	REG(0, 's'),
-	REG(0, 't'),
 	REG(0, 'v'),
 };
 
@@ -153,6 +152,8 @@
 		n_s0 = n_s;
 		n_f0 = n_f;
 		n_na = 0;
+		adj_ll(env->adj, n_l);
+		adj_in(env->adj, n_i);
 	}
 }
 
--- a/ren.c
+++ b/ren.c
@@ -4,8 +4,6 @@
 #include <string.h>
 #include "xroff.h"
 
-#define ADJ_LL		(n_u ? n_l - n_i : 0)	/* effective line length */
-#define ADJ_B		(n_u && !n_na && n_j == AD_B)
 #define cadj		env_adj()		/* line buffer */
 
 /* diversions */
@@ -179,10 +177,13 @@
 	int prev_d = n_d;
 	int ljust = 0;
 	char cmd[32];
+	int ll, li, lt, linelen;
 	ren_sp(0);
 	n_n = w;
+	adj_conf(cadj, &ll, &li, &lt);
+	linelen = ll - li - lt;
 	if (n_u && !n_na && (n_j == AD_C || n_j == AD_R))
-		ljust = n_j == AD_C ? (ADJ_LL - w) / 2 : ADJ_LL - w;
+		ljust = n_j == AD_C ? (linelen - w) / 2 : linelen - w;
 	if (cdiv) {
 		if (cdiv->dl < w)
 			cdiv->dl = w;
@@ -192,7 +193,7 @@
 		}
 		sbuf_append(&cdiv->sbuf, out);
 	} else {
-		OUT("H%d\n", n_o + n_i + ljust);
+		OUT("H%d\n", n_o + li + lt + ljust);
 		OUT("V%d\n", n_d);
 		output(out);
 	}
@@ -203,9 +204,10 @@
 static void ren_br(int force)
 {
 	char out[LNLEN];
-	int w;
+	int adj_b, w;
 	if (!adj_empty(cadj, n_u)) {
-		w = adj_fill(cadj, !force && ADJ_B, force ? 0: ADJ_LL, out);
+		adj_b = n_u && !n_na && n_j == AD_B;
+		w = adj_fill(cadj, !force && adj_b, !force && n_u, out);
 		out_line(out, w);
 	}
 }
@@ -262,6 +264,14 @@
 	ren_ps(args[1]);
 }
 
+void tr_ll(char **args)
+{
+	int ll = args[1] ? eval(args[1], n_l, 'm') : n_l0;
+	n_l0 = n_l;
+	n_l = ll;
+	adj_ll(cadj, ll);
+}
+
 void tr_in(char **args)
 {
 	int in = args[1] ? eval(args[1], n_i, 'm') : n_i0;
@@ -269,6 +279,7 @@
 		ren_br(1);
 	n_i0 = n_i;
 	n_i = in;
+	adj_in(cadj, in);
 }
 
 void tr_ti(char **args)
@@ -276,7 +287,7 @@
 	if (args[0][0] == '.')
 		ren_br(1);
 	if (args[1])
-		n_ti = eval(args[1], 0, 'm');
+		adj_ti(cadj, eval(args[1], 0, 'm'));
 }
 
 static void ren_ft(char *s)
@@ -400,10 +411,6 @@
 			return 0;
 		}
 	}
-	if (n_ti && adj_empty(cadj, n_u)) {
-		adj_put(adj, n_ti, "\\h'%du'", n_ti);
-		n_ti = 0;
-	}
 	if (ren_s != n_s) {
 		adj_swid(adj, charwid(dev_spacewid(), n_s));
 		adj_put(adj, 0, "\\s(%02d", n_s);
@@ -431,6 +438,7 @@
 	int type = 0;
 	wid_c = ren_next();
 	c = ren_next();
+	adj_ll(adj, n_l);
 	odiv_beg();
 	while (c >= 0 && c != wid_c) {
 		ren_back(c);
@@ -455,7 +463,7 @@
 			ren_back(c);
 			render_char(cadj);
 		}
-		while (adj_full(cadj, ADJ_LL))
+		while (adj_full(cadj, n_u))
 			ren_br(0);
 		if (c != ' ' && c != '\n') {
 			ren_back(c);
--- a/tr.c
+++ b/tr.c
@@ -14,13 +14,6 @@
 	} while (c >= 0 && c != '\n');
 }
 
-static void tr_ll(char **args)
-{
-	int ll = args[1] ? eval(args[1], n_l, 'm') : n_l0;
-	n_l0 = n_l;
-	n_l = ll;
-}
-
 static void tr_vs(char **args)
 {
 	int vs = args[1] ? eval(args[1], n_v, 'p') : n_v0;
--- a/xroff.h
+++ b/xroff.h
@@ -127,6 +127,7 @@
 void tr_fp(char **args);
 void tr_ft(char **args);
 void tr_in(char **args);
+void tr_ll(char **args);
 void tr_ne(char **args);
 void tr_nf(char **args);
 void tr_ps(char **args);
@@ -167,12 +168,16 @@
 
 struct adj *adj_alloc(void);
 void adj_free(struct adj *adj);
-int adj_fill(struct adj *adj, int ad_b, int linelen, char *dst);
+int adj_fill(struct adj *adj, int ad_b, int fill, 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 linelen);
+int adj_full(struct adj *adj, int fill);
 int adj_empty(struct adj *adj, int fill);
 int adj_wid(struct adj *adj);
+void adj_ll(struct adj *adj, int ll);
+void adj_in(struct adj *adj, int in);
+void adj_ti(struct adj *adj, int ti);
+void adj_conf(struct adj *adj, int *ll, int *in, int *ti);
 
 /* builtin number registers; n_X for .X register */
 #define REG(c1, c2)	((c1) * 256 + (c2))
@@ -200,7 +205,6 @@
 #define n_na		(*nreg(REG(0, 'n')))	/* .na mode */
 #define n_o0		(*nreg(REG(0, 'o')))	/* last .o */
 #define n_s0		(*nreg(REG(0, 's')))	/* last .s */
-#define n_ti		(*nreg(REG(0, 't')))	/* temp indent */
 #define n_v0		(*nreg(REG(0, 'v')))	/* last .v */
 
 /* functions for implementing read-only registers */