shithub: neatroff

Download patch

ref: f7fb552fa7ca7a294f5a0c02375c5824ff27d9a2
parent: 2f3b2e4ea1c54152878fba61181b0099479d4501
author: Ali Gholami Rudi <ali@rudi.ir>
date: Sat Apr 13 21:39:34 EDT 2013

ren: add .ad and .na

--- a/adj.c
+++ b/adj.c
@@ -31,9 +31,9 @@
 }
 
 /* does the adjustment buffer need to be flushed? */
-int adj_full(struct adj *a, int mode, int linelen)
+int adj_full(struct adj *a, int linelen)
 {
-	if (mode == ADJ_N)
+	if (!linelen)
 		return a->nls;
 	if (adj_fullnf(a))
 		return 1;
@@ -41,9 +41,9 @@
 }
 
 /* is the adjustment buffer empty? */
-int adj_empty(struct adj *a, int mode)
+int adj_empty(struct adj *a, int fill)
 {
-	return mode == ADJ_N ? !a->nls : !a->nwords && !adj_fullnf(a);
+	return !fill ? !a->nls : !a->nwords && !adj_fullnf(a);
 }
 
 /* set space width */
@@ -83,12 +83,12 @@
 }
 
 /* fill and copy a line into s */
-int adj_fill(struct adj *a, int mode, int ll, char *s)
+int adj_fill(struct adj *a, int ad_b, int ll, char *s)
 {
 	int adj_div, adj_rem;
 	int w = 0;
 	int i, n;
-	if (mode == ADJ_N || adj_fullnf(a)) {
+	if (!ll || adj_fullnf(a)) {
 		a->nls--;
 		return adj_move(a, a->nwords, s);
 	}
@@ -97,7 +97,7 @@
 			break;
 		w += a->words[n].wid + a->words[n].gap;
 	}
-	if (mode == ADJ_B && n > 1 && n < a->nwords) {
+	if (ad_b && n > 1 && n < a->nwords) {
 		adj_div = (ll - w) / (n - 1);
 		adj_rem = ll - w - adj_div * (n - 1);
 		a->wid += ll - w;
--- a/reg.c
+++ b/reg.c
@@ -28,6 +28,7 @@
 	REG('.', 'u'),
 	REG('.', 'v'),
 	REG(0, 'f'),
+	REG(0, 'n'),
 	REG(0, 's'),
 	REG(0, 't'),
 };
@@ -118,7 +119,7 @@
 		env->adj = adj_alloc();
 		n_f = 1;
 		n_i = 0;
-		n_j = 1;
+		n_j = AD_B;
 		n_l = SC_IN * 65 / 10;
 		n_s = 10;
 		n_u = 1;
@@ -125,6 +126,7 @@
 		n_v = 12 * SC_PT;
 		n_s0 = n_s;
 		n_f0 = n_f;
+		n_na = 0;
 	}
 }
 
--- a/ren.c
+++ b/ren.c
@@ -4,8 +4,8 @@
 #include <string.h>
 #include "xroff.h"
 
-#define ADJ_LL		(n_l - n_i)		/* effective line length */
-#define ADJ_MODE	(n_u ? n_j : ADJ_N)
+#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 */
@@ -177,14 +177,22 @@
 static void out_line(char *out, int w)
 {
 	int prev_d = n_d;
+	int ljust = 0;
+	char cmd[32];
 	ren_sp(0);
 	n_n = w;
+	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;
 	if (cdiv) {
 		if (cdiv->dl < w)
 			cdiv->dl = w;
+		if (ljust) {
+			sprintf(cmd, "\\h'%du'", ljust);
+			sbuf_append(&cdiv->sbuf, cmd);
+		}
 		sbuf_append(&cdiv->sbuf, out);
 	} else {
-		OUT("H%d\n", n_o + n_i);
+		OUT("H%d\n", n_o + n_i + ljust);
 		output(out);
 	}
 	if (!ren_traps(prev_d, n_d, 0))
@@ -195,8 +203,8 @@
 {
 	char out[LNLEN];
 	int w;
-	if (!adj_empty(cadj, ADJ_MODE)) {
-		w = adj_fill(cadj, force ? ADJ_N : ADJ_MODE, ADJ_LL, out);
+	if (!adj_empty(cadj, n_u)) {
+		w = adj_fill(cadj, !force && ADJ_B, force ? 0: ADJ_LL, out);
 		out_line(out, w);
 	}
 }
@@ -386,7 +394,7 @@
 			return 0;
 		}
 	}
-	if (n_ti && adj_empty(cadj, ADJ_MODE)) {
+	if (n_ti && adj_empty(cadj, n_u)) {
 		adj_put(adj, n_ti, "\\h'%du'", n_ti);
 		n_ti = 0;
 	}
@@ -441,7 +449,7 @@
 			ren_back(c);
 			render_char(cadj);
 		}
-		while (adj_full(cadj, ADJ_MODE, ADJ_LL))
+		while (adj_full(cadj, ADJ_LL))
 			ren_br(0);
 		if (c != ' ' && c != '\n') {
 			ren_back(c);
--- a/tr.c
+++ b/tr.c
@@ -220,9 +220,35 @@
 
 static void tr_na(char **args)
 {
-	n_j = 0;
+	n_na = 1;
 }
 
+static void tr_ad(char **args)
+{
+	n_na = 0;
+	if (!args[1])
+		return;
+	switch (args[1][0]) {
+	case '0' + AD_L:
+	case 'l':
+		n_j = AD_L;
+		break;
+	case '0' + AD_R:
+	case 'r':
+		n_j = AD_R;
+		break;
+	case '0' + AD_C:
+	case 'c':
+		n_j = AD_C;
+		break;
+	case '0' + AD_B:
+	case 'b':
+	case 'n':
+		n_j = AD_B;
+		break;
+	}
+}
+
 static void tr_tm(char **args)
 {
 	fprintf(stderr, "%s\n", args[1]);
@@ -366,6 +392,7 @@
 } cmds[] = {
 	{DIV_BEG + 1, tr_divbeg},
 	{DIV_END + 1, tr_divend},
+	{"ad", tr_ad},
 	{"am", tr_de, mkargs_reg1},
 	{"as", tr_as, mkargs_ds},
 	{"bp", tr_bp},
--- a/xroff.h
+++ b/xroff.h
@@ -152,17 +152,18 @@
 #define DIV_END		".&>"
 
 /* adjustment */
-#define ADJ_L		0
-#define ADJ_B		1
-#define ADJ_N		2		/* no adjustment (.nf) */
+#define AD_L		0
+#define AD_B		1
+#define AD_C		3
+#define AD_R		5
 
 struct adj *adj_alloc(void);
 void adj_free(struct adj *adj);
-int adj_fill(struct adj *adj, int mode, int linelen, char *dst);
+int adj_fill(struct adj *adj, int ad_b, 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);
-int adj_empty(struct adj *adj, int mode);
+int adj_full(struct adj *adj, int linelen);
+int adj_empty(struct adj *adj, int fill);
 int adj_wid(struct adj *adj);
 
 /* builtin number registers; n_X for .X register */
@@ -184,8 +185,9 @@
 #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 */
 #define n_lb		(*nreg(REG(0, 'b')))	/* input line beg */
+#define n_f0		(*nreg(REG(0, 'f')))	/* last font */
+#define n_na		(*nreg(REG(0, 'n')))	/* .na mode */
 #define n_s0		(*nreg(REG(0, 's')))	/* last size */
 #define n_ti		(*nreg(REG(0, 't')))	/* temp indent */