shithub: neatroff

Download patch

ref: 915a5bc3e66f4462cc28e68361c6de4e7a8f34e1
parent: e17e491c13f8cc81ab1c9cb519441c376686e91b
author: Ali Gholami Rudi <ali@rudi.ir>
date: Fri Aug 8 19:50:15 EDT 2014

cp: handle conditional blocks with no spaces between .ie/.if and \{

--- a/cp.c
+++ b/cp.c
@@ -4,9 +4,9 @@
 #include <string.h>
 #include "roff.h"
 
-static int cp_nblk;		/* input block depth (text in \{ and \}) */
-static int cp_sblk[NIES];	/* skip \} escape at this depth, if set */
+static int cp_blkdep;		/* input block depth (text in \{ and \}) */
 static int cp_cpmode;		/* disable the interpretation \w and \E */
+static int cp_preblk;		/* prefix \{ with this character until an EOL */
 
 static void cparg(char *d, int len)
 {
@@ -168,14 +168,21 @@
 			in_back('');
 			return c_ni;
 		}
-		if (c == '{' && cp_nblk < LEN(cp_sblk))
-			cp_sblk[cp_nblk++] = 0;
-		if (c == '}' && cp_nblk > 0)
-			if (cp_sblk[--cp_nblk])
-				return cp_raw();
+		if (c == '}' && cp_blkdep > 0)
+			cp_blkdep--;
+		if (c == '{') {
+			cp_blkdep++;
+			if (cp_preblk > 0) {
+				in_back(c);
+				in_back(c_ec);
+				return cp_preblk;
+			}
+		}
 		in_back(c);
 		return c_ec;
 	}
+	if (c == '\n')
+		cp_preblk = 0;
 	return c;
 }
 
@@ -224,20 +231,18 @@
 void cp_blk(int skip)
 {
 	int c;
-	int nblk = cp_nblk;
 	do {
 		c = skip ? cp_raw() : cp_next();
 	} while (c == ' ' || c == '\t');
 	if (skip) {
-		while (c >= 0 && (c != '\n' || cp_nblk > nblk))
+		int dep = c == c_ec && in_top() == '{' ? cp_blkdep - 1 : cp_blkdep;
+		while (c >= 0 && (c != '\n' || cp_blkdep > dep))
 			c = cp_raw();
 	} else {
-		if (c == c_ec && in_top() == '{') {	/* a troff \{ \} block */
-			cp_sblk[nblk] = 1;
+		if (c == c_ec && in_top() == '{')	/* a troff \{ \} block */
 			cp_raw();
-		} else {
+		else
 			cp_back(c);
-		}
 	}
 }
 
@@ -244,4 +249,10 @@
 void cp_copymode(int mode)
 {
 	cp_cpmode = mode;
+}
+
+/* prefix \{ with c until an EOL; the main reason is handling .ie\{ */
+void cp_prefixblock(int c)
+{
+	cp_preblk = c;
 }
--- a/roff.h
+++ b/roff.h
@@ -207,6 +207,7 @@
 int in_lnum(void);		/* current line number */
 
 void cp_blk(int skip);		/* skip or read the next line or block */
+void cp_prefixblock(int c);	/* prefix \{ with c until an EOL */
 void cp_copymode(int mode);	/* do not interpret \w and \E */
 #define cp_back		in_back	/* cp.c is stateless */
 int tr_nextreq(void);		/* read the next troff request */
--- a/tr.c
+++ b/tr.c
@@ -966,6 +966,7 @@
 	args[0] = cmd;
 	cmd[0] = c;
 	req = NULL;
+	cp_prefixblock(' ');
 	read_regname(cmd + 1);
 	sbuf_init(&sbuf);
 	req = str_dget(map(cmd + 1));