shithub: neatroff

Download patch

ref: 2f3b2e4ea1c54152878fba61181b0099479d4501
parent: 62e35b0cbb72f98624811466fa9dffafa58a0fde
author: Ali Gholami Rudi <ali@rudi.ir>
date: Sat Apr 13 19:06:26 EDT 2013

ren: \v and \h, absolute positions with |, and .ti

--- a/eval.c
+++ b/eval.c
@@ -3,6 +3,7 @@
 #include "xroff.h"
 
 static int defunit = 0;		/* default scale indicator */
+static int abspos = 0;		/* absolute position like |1i */
 
 static int readunit(int c, int *mul, int *div)
 {
@@ -87,6 +88,8 @@
 		return -evalatom(s);
 	if (!evaljmp(s, '+'))
 		return evalatom(s);
+	if (!evaljmp(s, '|'))
+		return abspos + evalatom(s);
 	if (evalisnum(s))
 		return evalnum(s);
 	if (!evaljmp(s, '(')) {
@@ -136,6 +139,10 @@
 		s++;
 	}
 	defunit = unit;
+	if (unit == 'v')
+		abspos = -n_d;
+	if (unit == 'm')
+		abspos = n_lb - n_k;
 	n = evalexpr(&s);
 	if (rel)
 		return rel > 0 ? orig + n : orig - n;
--- a/out.c
+++ b/out.c
@@ -92,7 +92,7 @@
 			if (c[0] == '(') {
 				s = utf8get(c, s);
 				s = utf8get(c + strlen(c), s);
-			} else if (strchr("sfhv", c[0])) {
+			} else if (strchr("fhsv", c[0])) {
 				s = escarg(s, arg, c[0]);
 				if (c[0] == 's') {
 					out_ps(eval(arg, o_s, '\0'));
@@ -107,7 +107,7 @@
 					continue;
 				}
 				if (c[0] == 'v') {
-					OUT("v%d", eval(arg, 0, 'm'));
+					OUT("v%d", eval(arg, 0, 'v'));
 					continue;
 				}
 			}
--- a/reg.c
+++ b/reg.c
@@ -29,6 +29,7 @@
 	REG('.', 'v'),
 	REG(0, 'f'),
 	REG(0, 's'),
+	REG(0, 't'),
 };
 
 /* return the address of a number register */
--- a/ren.c
+++ b/ren.c
@@ -4,9 +4,9 @@
 #include <string.h>
 #include "xroff.h"
 
-#define ADJ_LL		(n_l - n_i)	/* effective line length */
+#define ADJ_LL		(n_l - n_i)		/* effective line length */
 #define ADJ_MODE	(n_u ? n_j : ADJ_N)
-#define cadj		env_adj()	/* line buffer */
+#define cadj		env_adj()		/* line buffer */
 
 /* diversions */
 struct div {
@@ -262,6 +262,14 @@
 		n_i = eval(args[1], n_i, 'm');
 }
 
+void tr_ti(char **args)
+{
+	if (args[0][0] == '.')
+		ren_br(1);
+	if (args[1])
+		n_ti = eval(args[1], 0, 'm');
+}
+
 static void ren_ft(char *s)
 {
 	int fn = !*s || !strcmp("P", s) ? n_f0 : dev_font(s);
@@ -344,10 +352,12 @@
 	char c[GNLEN * 2];
 	char arg[ILNLEN];
 	struct glyph *g;
-	int esc = 0;
+	int esc = 0, n;
 	nextchar(c);
+	if (c[0] == '\n')
+		n_lb = adj_wid(cadj);
 	if (c[0] == ' ' || c[0] == '\n') {
-		adj_put(cadj, charwid(dev_spacewid(), n_s), c);
+		adj_put(adj, charwid(dev_spacewid(), n_s), c);
 		return 0;
 	}
 	if (c[0] == '\\') {
@@ -357,7 +367,7 @@
 			int l = nextchar(c);
 			l += nextchar(c + l);
 			c[l] = '\0';
-		} else if (strchr("sfw", c[0])) {
+		} else if (strchr("fhsvw", c[0])) {
 			if (c[0] == 'w') {
 				render_wid();
 				return 0;
@@ -365,10 +375,20 @@
 			escarg_ren(arg, c[0]);
 			if (c[0] == 'f')
 				ren_ft(arg);
+			if (c[0] == 'h') {
+				n = eval(arg, 0, 'm');
+				adj_put(adj, n, "\\h'%du'", n);
+			}
 			if (c[0] == 's')
 				ren_ps(arg);
+			if (c[0] == 'v')
+				adj_put(adj, 0, "\\v'%du'", eval(arg, 0, 'v'));
 			return 0;
 		}
+	}
+	if (n_ti && adj_empty(cadj, ADJ_MODE)) {
+		adj_put(adj, n_ti, "\\h'%du'", n_ti);
+		n_ti = 0;
 	}
 	if (ren_s != n_s) {
 		adj_swid(adj, charwid(dev_spacewid(), n_s));
--- a/tr.c
+++ b/tr.c
@@ -394,6 +394,7 @@
 	{"rm", tr_rm},
 	{"rn", tr_rn},
 	{"sp", tr_sp},
+	{"ti", tr_ti},
 	{"tm", tr_tm, mkargs_eol},
 	{"vs", tr_vs},
 	{"wh", tr_wh},
--- a/xroff.h
+++ b/xroff.h
@@ -123,6 +123,7 @@
 void tr_nf(char **args);
 void tr_ps(char **args);
 void tr_sp(char **args);
+void tr_ti(char **args);
 void tr_wh(char **args);
 
 void tr_init(void);
@@ -184,7 +185,9 @@
 #define n_nl		(*nreg(REG('n', 'l')))
 #define n_pg		(*nreg(REG('%', '\0')))	/* % */
 #define n_f0		(*nreg(REG(0, 'f')))	/* last font */
+#define n_lb		(*nreg(REG(0, 'b')))	/* input line beg */
 #define n_s0		(*nreg(REG(0, 's')))	/* last size */
+#define n_ti		(*nreg(REG(0, 't')))	/* temp indent */
 
 /* functions for implementing read-only registers */
 int f_nexttrap(void);	/* .t */