shithub: neatroff

Download patch

ref: c442e7df2875ac2b71baa69b0f6f9b11195a78cc
parent: a0a39eaf9c338a38464e6bc139bc4a4460fc6748
author: Ali Gholami Rudi <ali@rudi.ir>
date: Mon Apr 15 13:35:31 EDT 2013

ren: add \D

--- a/out.c
+++ b/out.c
@@ -80,6 +80,86 @@
 	return s;
 }
 
+static char *tok_str(char *d, char *s)
+{
+	while (isspace(*s))
+		s++;
+	while (*s && !isspace(*s))
+		*d++ = *s++;
+	*d = '\0';
+	return s;
+}
+
+static char *tok_num(int *d, char *s, char **cc, int scale)
+{
+	char tok[ILNLEN];
+	s = tok_str(tok, s);
+	*d = eval(tok, 0, scale);
+	if (*cc)
+		*cc += sprintf(*cc, " %du", *d);
+	else
+		OUT(" %d", *d);
+	return s;
+}
+
+/* parse \D arguments and copy them into cc; return the width */
+int out_draw(char *s, char *cc)
+{
+	int h1, h2, v1, v2;
+	int hd = 0, vd = 0;
+	int c = *s++;
+	if (cc)
+		*cc++ = c;
+	else
+		OUT("D%c", c);
+	switch (c) {
+	case 'l':
+		s = tok_num(&h1, s, &cc, 'm');
+		s = tok_num(&v1, s, &cc, 'v');
+		if (!cc)			/* dpost requires this */
+			OUT(" .");
+		hd = h1;
+		vd = v1;
+		break;
+	case 'c':
+		s = tok_num(&h1, s, &cc, 'm');
+		hd = h1;
+		vd = 0;
+		break;
+	case 'e':
+		s = tok_num(&h1, s, &cc, 'm');
+		s = tok_num(&v1, s, &cc, 'v');
+		hd = h1;
+		vd = 0;
+		break;
+	case 'a':
+		s = tok_num(&h1, s, &cc, 'm');
+		s = tok_num(&v1, s, &cc, 'v');
+		s = tok_num(&h2, s, &cc, 'm');
+		s = tok_num(&v2, s, &cc, 'v');
+		hd = h1 + h2;
+		vd = v1 + v2;
+		break;
+	default:
+		s = tok_num(&h1, s, &cc, 'm');
+		s = tok_num(&v1, s, &cc, 'v');
+		hd = h1;
+		vd = v1;
+		while (*s) {
+			s = tok_num(&h2, s, &cc, 'm');
+			s = tok_num(&v2, s, &cc, 'v');
+			hd += h2;
+			vd += v2;
+		}
+		break;
+	}
+	if (cc)
+		*cc = '\0';
+	else
+		OUT("\n");
+	return hd;
+}
+
 void output(char *s)
 {
 	struct glyph *g;
@@ -92,10 +172,10 @@
 			if (c[0] == '(') {
 				s = utf8get(c, s);
 				s = utf8get(c + strlen(c), s);
-			} else if (strchr("fhsv", c[0])) {
+			} else if (strchr("Dfhsv", c[0])) {
 				s = escarg(s, arg, c[0]);
-				if (c[0] == 's') {
-					out_ps(eval(arg, o_s, '\0'));
+				if (c[0] == 'D') {
+					out_draw(arg, NULL);
 					continue;
 				}
 				if (c[0] == 'f') {
@@ -104,6 +184,10 @@
 				}
 				if (c[0] == 'h') {
 					OUT("h%d", eval(arg, 0, 'm'));
+					continue;
+				}
+				if (c[0] == 's') {
+					out_ps(eval(arg, o_s, '\0'));
 					continue;
 				}
 				if (c[0] == 'v') {
--- a/ren.c
+++ b/ren.c
@@ -193,6 +193,7 @@
 		sbuf_append(&cdiv->sbuf, out);
 	} else {
 		OUT("H%d\n", n_o + n_i + ljust);
+		OUT("V%d\n", n_d);
 		output(out);
 	}
 	if (!ren_traps(prev_d, n_d, 0))
@@ -359,8 +360,9 @@
 {
 	char c[GNLEN * 2];
 	char arg[ILNLEN];
+	char draw_arg[ILNLEN];
 	struct glyph *g;
-	int esc = 0, n;
+	int esc = 0, n, w;
 	nextchar(c);
 	if (c[0] == '\n')
 		n_lb = adj_wid(cadj);
@@ -375,12 +377,16 @@
 			int l = nextchar(c);
 			l += nextchar(c + l);
 			c[l] = '\0';
-		} else if (strchr("fhsvw", c[0])) {
+		} else if (strchr("Dfhsvw", c[0])) {
 			if (c[0] == 'w') {
 				render_wid();
 				return 0;
 			}
 			escarg_ren(arg, c[0]);
+			if (c[0] == 'D') {
+				w = out_draw(arg, draw_arg);
+				adj_put(adj, w, "\\D'%s'", draw_arg);
+			}
 			if (c[0] == 'f')
 				ren_ft(arg);
 			if (c[0] == 'h') {
--- a/xroff.h
+++ b/xroff.h
@@ -109,6 +109,7 @@
 void render(void);	/* read from in.c and print the output */
 void output(char *s);	/* output the given rendered line */
 void ren_page(int pg);
+int out_draw(char *s, char *cc);
 
 /* troff commands */
 void tr_bp(char **args);