shithub: neatroff

Download patch

ref: 9521c10a1a8fcbe1bbfedb531f276038c0598a51
parent: 18625279e9fc3b144e80e4a2755fd82f6a3ded2f
author: Ali Gholami Rudi <ali@rudi.ir>
date: Wed Nov 12 17:25:10 EST 2014

ren: escaped percent signs in .tl arguments

--- a/ren.c
+++ b/ren.c
@@ -810,8 +810,8 @@
 }
 
 /* return 1 if d1 was read and 2 if d2 was read */
-static int ren_until(struct wb *wb, char *d1, char *d2,
-			int (*next)(void), void (*back)(int))
+static int ren_until(struct wb *wb, int (*next)(void), void (*back)(int),
+			char *d1, char *d2)
 {
 	int c, ret;
 	c = next();
@@ -827,6 +827,19 @@
 	return 0;
 }
 
+/* like ren_until(); map src to dst */
+static int ren_untilmap(struct wb *wb, int (*next)(void), void (*back)(int),
+			char *end, char *src, char *dst)
+{
+	int ret;
+	while ((ret = ren_until(wb, next, back, src, end)) == 1) {
+		sstr_push(dst);
+		ren_until(wb, sstr_next, sstr_back, end, NULL);
+		sstr_pop();
+	}
+	return 0;
+}
+
 static void wb_cpy(struct wb *dst, struct wb *src, int left)
 {
 	wb_hmov(dst, left - wb_wid(dst));
@@ -836,6 +849,8 @@
 void ren_tl(int (*next)(void), void (*back)(int))
 {
 	struct wb wb, wb2;
+	char src[4] = {c_pc};
+	char *dst = num_str(map("%"));
 	char delim[GNLEN];
 	wb_init(&wb);
 	wb_init(&wb2);
@@ -843,13 +858,13 @@
 	if (!strcmp("\n", delim))
 		back('\n');
 	/* the left-adjusted string */
-	ren_until(&wb2, delim, NULL, next, back);
+	ren_untilmap(&wb2, next, back, delim, src, dst);
 	wb_cpy(&wb, &wb2, 0);
 	/* the centered string */
-	ren_until(&wb2, delim, NULL, next, back);
+	ren_untilmap(&wb2, next, back, delim, src, dst);
 	wb_cpy(&wb, &wb2, (n_lt - wb_wid(&wb2)) / 2);
 	/* the right-adjusted string */
-	ren_until(&wb2, delim, NULL, next, back);
+	ren_untilmap(&wb2, next, back, delim, src, dst);
 	wb_cpy(&wb, &wb2, n_lt - wb_wid(&wb2));
 	/* flushing the line */
 	ren_line(wb_buf(&wb), wb_wid(&wb), AD_L, 0,
@@ -867,7 +882,7 @@
 	int pad, rem;
 	while (n < LEN(wbs)) {
 		wb_init(&wbs[n]);
-		if (ren_until(&wbs[n++], c_fb, c_fa, next, back) != 1)
+		if (ren_until(&wbs[n++], next, back, c_fb, c_fa) != 1)
 			break;
 	}
 	left = wb == cwb ? f_hpos() : wb_wid(wb);
--- a/roff.h
+++ b/roff.h
@@ -69,6 +69,7 @@
 extern int c_ec;	/* escape character (\) */
 extern int c_cc;	/* basic control character (.) */
 extern int c_c2;	/* no-break control character (') */
+extern int c_pc;	/* page number character */
 #define c_ni	4	/* non-interpreted copy-mode escape */
 #define c_hc	env_hc()/* hyphenation character */
 #define c_mc	env_mc()/* margin character (.mc) */
--- a/tr.c
+++ b/tr.c
@@ -6,7 +6,7 @@
 #include "roff.h"
 
 static int tr_nl = 1;		/* just read a newline */
-static int c_pc = '%';		/* page number character */
+int c_pc = '%';			/* page number character */
 int c_ec = '\\';
 int c_cc = '.';
 int c_c2 = '\'';
@@ -359,16 +359,6 @@
 	c_pc = args[1] ? args[1][0] : -1;
 }
 
-static int tl_next(void)
-{
-	int c = cp_next();
-	if (c >= 0 && c == c_pc) {
-		in_push(num_str(map("%")), NULL);
-		c = cp_next();
-	}
-	return c;
-}
-
 static void tr_tl(char **args)
 {
 	int c;
@@ -376,7 +366,7 @@
 		c = cp_next();
 	} while (c >= 0 && (c == ' ' || c == '\t'));
 	cp_back(c);
-	ren_tl(tl_next, cp_back);
+	ren_tl(cp_next, cp_back);
 	do {
 		c = cp_next();
 	} while (c >= 0 && c != '\n');