shithub: neatroff

Download patch

ref: d7cc1c7e69a3b403e63ada5ead6600e86a2dd40f
parent: bb8d4fe83ef6e55a2189b1563512d129fc419700
author: Ali Gholami Rudi <ali@rudi.ir>
date: Mon May 6 06:48:09 EDT 2013

ren: support fields

--- a/ren.c
+++ b/ren.c
@@ -31,6 +31,9 @@
 static int bp_next = 1;		/* next page number */
 static int bp_force;		/* execute the traps until the next page */
 
+static int c_fa;		/* field delimiter */
+static char c_fb[GNLEN];	/* field padding */
+
 static int ren_next(void)
 {
 	return ren_un > 0 ? ren_unbuf[--ren_un] : tr_next();
@@ -434,6 +437,17 @@
 	n_ce = args[1] ? atoi(args[1]) : 1;
 }
 
+void tr_fc(char **args)
+{
+	if (args[1]) {
+		c_fa = args[1][0];
+		strcpy(c_fb, args[2] ? args[2] : " ");
+	} else {
+		c_fa = -1;
+		c_fb[0] = '\0';
+	}
+}
+
 static void escarg_ren(char *d, int cmd, int (*next)(void), void (*back)(int))
 {
 	char delim[GNLEN];
@@ -555,6 +569,8 @@
 	}
 }
 
+static void ren_field(struct wb *wb, 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))
 {
@@ -572,6 +588,10 @@
 		wb_hmov(wb, tab_next(n) - n);
 		return;
 	}
+	if (c[0] == c_fa) {
+		ren_field(wb, next, back);
+		return;
+	}
 	if (c[0] == c_ec) {
 		nextchar(c + 1, next);
 		if (c[1] == '(') {
@@ -630,11 +650,13 @@
 	return n;
 }
 
-static void ren_until(struct wb *wb, char *delim, int (*next)(void), void (*back)(int))
+/* return 1 if the ending character (ec) was read */
+static int ren_until(struct wb *wb, char *delim, int ec,
+			int (*next)(void), void (*back)(int))
 {
 	int c;
 	c = next();
-	while (c >= 0 && c != '\n') {
+	while (c >= 0 && c != '\n' && c != ec) {
 		back(c);
 		if (!schar_jump(delim, next, back))
 			break;
@@ -643,6 +665,7 @@
 	}
 	if (c == '\n')
 		back(c);
+	return c == ec;
 }
 
 static void wb_cpy(struct wb *dst, struct wb *src, int left)
@@ -661,13 +684,13 @@
 	wb_init(&wb2);
 	schar_read(delim, next);
 	/* the left-adjusted string */
-	ren_until(&wb2, delim, next, back);
+	ren_until(&wb2, delim, '\n', next, back);
 	wb_cpy(&wb, &wb2, 0);
 	/* the centered string */
-	ren_until(&wb2, delim, next, back);
+	ren_until(&wb2, delim, '\n', next, back);
 	wb_cpy(&wb, &wb2, (n_lt - wb_wid(&wb2)) / 2);
 	/* the right-adjusted string */
-	ren_until(&wb2, delim, next, back);
+	ren_until(&wb2, delim, '\n', next, back);
 	wb_cpy(&wb, &wb2, n_lt - wb_wid(&wb2));
 	/* flushing the line */
 	adj_ll(adj, n_lt);
@@ -677,6 +700,36 @@
 	adj_free(adj);
 	wb_done(&wb2);
 	wb_done(&wb);
+}
+
+static void ren_field(struct wb *wb, int (*next)(void), void (*back)(int))
+{
+	struct wb wbs[NFIELDS];
+	int i, n = 0;
+	int wid = 0;
+	int left, right, cur_left;
+	int pad, rem;
+	while (n < LEN(wbs)) {
+		wb_init(&wbs[n]);
+		if (ren_until(&wbs[n++], c_fb, c_fa, next, back))
+			break;
+	}
+	left = wb == &ren_wb ? f_hpos() : wb_wid(wb);
+	right = tab_next(left);
+	for (i = 0; i < n; i++)
+		wid += wb_wid(&wbs[i]);
+	pad = (right - left - wid) / (n > 1 ? n - 1 : 1);
+	rem = (right - left - wid) % (n > 1 ? n - 1 : 1);
+	for (i = 0; i < n; i++) {
+		if (i == 0)
+			cur_left = left;
+		else if (i == n - 1)
+			cur_left = right - wb_wid(&wbs[i]);
+		else
+			cur_left = wb_wid(wb) + pad + (i + rem >= n);
+		wb_cpy(wb, &wbs[i], cur_left);
+		wb_done(&wbs[i]);
+	}
 }
 
 /* read characters from in.c and pass rendered lines to out.c */
--- a/tr.c
+++ b/tr.c
@@ -582,6 +582,7 @@
 	{"eo", tr_eo},
 	{"ev", tr_ev},
 	{"ex", tr_ex},
+	{"fc", tr_fc},
 	{"fi", tr_fi},
 	{"fp", tr_fp},
 	{"ft", tr_ft},
--- a/xroff.h
+++ b/xroff.h
@@ -20,7 +20,8 @@
 #define NPREV		16	/* environment stack depth */
 #define NTRAPS		1024	/* number of traps per page */
 #define NIES		128	/* number of nested .ie commands */
-#define NTABS		16	/* the number of tab stops */
+#define NTABS		16	/* number of tab stops */
+#define NFIELDS		32	/* number of fields */
 
 /* escape sequences */
 #define ESC_Q	"bCDhHlLNoSvwxX"	/* quoted escape sequences */
@@ -34,7 +35,7 @@
 extern int c_ec;	/* escape character (\) */
 extern int c_cc;	/* basic control character (.) */
 extern int c_c2;	/* no-break control character (') */
-#define c_ni	3	/* non-interpreted copy mode escape */
+#define c_ni	4	/* non-interpreted copy mode escape */
 
 /* number registers */
 int num_get(int id, int inc);
@@ -223,6 +224,7 @@
 void tr_divend(char **args);
 void tr_dt(char **args);
 void tr_ev(char **args);
+void tr_fc(char **args);
 void tr_fi(char **args);
 void tr_fp(char **args);
 void tr_ft(char **args);