shithub: neatroff

Download patch

ref: e4eb154d9ae6e0d3d7d2669e363820b9c3c8fc1a
parent: 5d02c6a0d1b06573e92154d2df5df0bcac744fd2
author: Ali Gholami Rudi <ali@rudi.ir>
date: Sun Jul 28 18:15:00 EDT 2013

ren: right adjusting and centering tab types

--- a/reg.c
+++ b/reg.c
@@ -11,6 +11,7 @@
 struct env {
 	int eregs[NENVS];	/* environment-specific number registers */
 	int tabs[NTABS];	/* tab stops */
+	char tabs_type[NTABS];	/* type of tabs: L, C, R */
 	struct adj *adj;	/* per environment line buffer */
 	char tc[GNLEN];		/* tab character (.tc) */
 	char lc[GNLEN];		/* leader character (.lc) */
@@ -306,17 +307,33 @@
 void tr_ta(char **args)
 {
 	int i;
-	for (i = 0; i < NARGS && args[i]; i++)
+	char *s;
+	for (i = 0; i < NARGS && args[i]; i++) {
 		env->tabs[i] = eval_re(args[i], i > 0 ? env->tabs[i - 1] : 0, 'm');
+		s = args[i][0] ? strchr(args[i], '\0') - 1 : "";
+		env->tabs_type[i] = strchr("LRC", *s) ? *s : 'L';
+	}
 }
 
-int tab_next(int pos)
+static int tab_idx(int pos)
 {
 	int i;
 	for (i = 0; i < LEN(env->tabs); i++)
 		if (env->tabs[i] > pos)
-			return env->tabs[i];
-	return pos;
+			return i;
+	return -1;
+}
+
+int tab_next(int pos)
+{
+	int i = tab_idx(pos);
+	return i >= 0 ? env->tabs[i] : pos;
+}
+
+int tab_type(int pos)
+{
+	int i = tab_idx(pos);
+	return i >= 0 && env->tabs_type[i] ? env->tabs_type[i] : 'L';
 }
 
 /* number register format (.af) */
--- a/ren.c
+++ b/ren.c
@@ -718,6 +718,7 @@
 }
 
 static void ren_field(struct wb *wb, int (*next)(void), void (*back)(int));
+static void ren_tab(struct wb *wb, char *tc, int (*next)(void), void (*back)(int));
 
 /* read one character and place it inside wb buffer */
 void ren_char(struct wb *wb, int (*next)(void), void (*back)(int))
@@ -725,7 +726,7 @@
 	char c[GNLEN * 4];
 	char arg[ILNLEN];
 	struct glyph *g;
-	char *s, *tc;
+	char *s;
 	int w, n, l;
 	nextchar(c, next);
 	if (c[0] == ' ' || c[0] == '\n') {
@@ -733,12 +734,7 @@
 		return;
 	}
 	if (c[0] == '\t' || c[0] == '') {
-		n = RENWB(wb) ? f_hpos() : wb_wid(wb);
-		tc = c[0] == '\t' ? c_tc : c_lc;
-		if (!tc[0])
-			wb_hmov(wb, tab_next(n) - n);
-		else
-			ren_hline(wb, tab_next(n) - n, tc);
+		ren_tab(wb, c[0] == '\t' ? c_tc : c_lc, next, back);
 		return;
 	}
 	if (c[0] == c_fa) {
@@ -905,6 +901,35 @@
 		wb_cpy(wb, &wbs[i], cur_left);
 		wb_done(&wbs[i]);
 	}
+}
+
+static void ren_tab(struct wb *wb, char *tc, int (*next)(void), void (*back)(int))
+{
+	struct wb t;
+	int pos = RENWB(wb) ? f_hpos() : wb_wid(wb);
+	int ins = tab_next(pos);	/* insertion position */
+	int typ = tab_type(pos);	/* tab type */
+	int c;
+	wb_init(&t);
+	if (typ == 'R' || typ == 'C') {
+		c = next();
+		while (c >= 0 && c != '\n' && c != '\t' && c != '') {
+			back(c);
+			ren_char(&t, next, back);
+			c = next();
+		}
+		back(c);
+	}
+	if (typ == 'C')
+		ins -= wb_wid(&t) / 2;
+	if (typ == 'R')
+		ins -= wb_wid(&t);
+	if (!tc[0] || ins <= pos)
+		wb_hmov(wb, ins - pos);
+	else
+		ren_hline(wb, ins - pos, tc);
+	wb_cat(wb, &t);
+	wb_done(&t);
 }
 
 /* read characters from in.c and pass rendered lines to out.c */
--- a/roff.h
+++ b/roff.h
@@ -80,6 +80,7 @@
 char *env_tc(void);
 char *env_lc(void);
 int tab_next(int pos);
+int tab_type(int pos);
 
 /* device related variables */
 extern int dev_res;