shithub: neatroff

Download patch

ref: 34ea5f4e771ff8af2f82f5683df3a9f47456751a
parent: fa8a3c6bfa5bfa31e159bc681cbb79b83d89428e
author: Ali Gholami Rudi <ali@rudi.ir>
date: Wed Mar 27 15:18:06 EDT 2013

ren: support nested diversions

--- a/ren.c
+++ b/ren.c
@@ -8,10 +8,16 @@
 #define ADJ_MODE	(n_u ? n_j : ADJ_N)
 #define adj		env_adj()	/* line buffer */
 
-static int ren_backed = -1;		/* pushed back character */
-static int ren_div;			/* current diversion */
-static struct sbuf out_div;		/* current diversion output */
+/* diversions */
+struct div {
+	struct sbuf sbuf;	/* diversion output */
+	int reg;		/* diversion register */
+};
+static struct div divs[NPREV];	/* diversion stack */
+static struct div *cdiv;	/* current diversion */
 
+static int ren_backed = -1;	/* pushed back character */
+
 static int ren_next(void)
 {
 	int c = ren_backed >= 0 ? ren_backed : tr_next();
@@ -40,7 +46,7 @@
 
 static void ren_ne(int n)
 {
-	if (n_nl + n > n_p && !ren_div)
+	if (n_nl + n > n_p && !cdiv)
 		ren_page(n_pg + 1);
 }
 
@@ -47,16 +53,17 @@
 void tr_di(char **args)
 {
 	if (args[1]) {
-		sbuf_init(&out_div);
-		ren_div = REG(args[1][0], args[1][1]);
-		if (args[0][2] == 'a')	/* .da */
-			sbuf_append(&out_div, str_get(ren_div));
+		cdiv = cdiv ? cdiv + 1 : divs;
+		sbuf_init(&cdiv->sbuf);
+		cdiv->reg = REG(args[1][0], args[1][1]);
+		if (args[0][2] == 'a' && str_get(cdiv->reg))	/* .da */
+			sbuf_append(&cdiv->sbuf, str_get(cdiv->reg));
 		n_d = 0;
-	} else if (ren_div) {
-		sbuf_putnl(&out_div);
-		str_set(ren_div, sbuf_buf(&out_div));
-		sbuf_done(&out_div);
-		ren_div = 0;
+	} else if (cdiv) {
+		sbuf_putnl(&cdiv->sbuf);
+		str_set(cdiv->reg, sbuf_buf(&cdiv->sbuf));
+		sbuf_done(&cdiv->sbuf);
+		cdiv = cdiv > divs ? cdiv - 1 : NULL;
 	}
 }
 
@@ -65,10 +72,10 @@
 {
 	char cmd[32];
 	n_d += n;
-	if (ren_div) {
-		sbuf_putnl(&out_div);
+	if (cdiv) {
+		sbuf_putnl(&cdiv->sbuf);
 		sprintf(cmd, ".sp %du\n", n);
-		sbuf_append(&out_div, cmd);
+		sbuf_append(&cdiv->sbuf, cmd);
 	} else {
 		n_nl = n_d;
 		if (n_nl <= n_p)
@@ -80,14 +87,14 @@
 static void out_line(char *out)
 {
 	char cmd[32];
-	if (ren_div) {
-		if (!sbuf_empty(&out_div))
+	if (cdiv) {
+		if (!sbuf_empty(&cdiv->sbuf))
 			down(n_v);
 		sprintf(cmd, "\\h'%d'", n_i);
-		sbuf_append(&out_div, DIV_BEG);
-		sbuf_append(&out_div, cmd);
-		sbuf_append(&out_div, out);
-		sbuf_append(&out_div, DIV_END);
+		sbuf_append(&cdiv->sbuf, DIV_BEG);
+		sbuf_append(&cdiv->sbuf, cmd);
+		sbuf_append(&cdiv->sbuf, out);
+		sbuf_append(&cdiv->sbuf, DIV_END);
 	} else {
 		down(n_v);
 		OUT("H%d\n", n_o + n_i);
@@ -132,7 +139,7 @@
 
 void tr_bp(char **args)
 {
-	if (!ren_div) {
+	if (!cdiv) {
 		ren_br(0, 1);
 		ren_page(args[1] ? tr_int(args[1], n_pg, 'v') : n_pg + 1);
 	}