shithub: neatroff

Download patch

ref: 35fd1a27372902e8d02190191e960133431c27f1
parent: 18ff8b8a94331d6d27a2daf7db61338a0523694e
author: Ali Gholami Rudi <ali@rudi.ir>
date: Wed May 1 15:44:22 EDT 2013

tr: add .cc, .c2, .ec and .eo

--- a/adj.c
+++ b/adj.c
@@ -87,7 +87,7 @@
 	*els_pos = 0;
 	for (i = 0; i < n; i++) {
 		cur = &a->words[i];
-		sbuf_printf(s, "\\h'%du'", cur->gap);
+		sbuf_printf(s, "%ch'%du'", c_ec, cur->gap);
 		sbuf_append(s, sbuf_buf(&cur->s));
 		sbuf_done(&cur->s);
 		w += cur->wid + cur->gap;
--- a/cp.c
+++ b/cp.c
@@ -64,7 +64,7 @@
 	if (in_top() >= 0)
 		return in_next();
 	c = in_next();
-	if (c == '\\') {
+	if (c == c_ec) {
 		c = in_next();
 		if (c == '\n')
 			return in_next();
@@ -76,7 +76,7 @@
 			if (cp_sblk[--cp_nblk])
 				return cp_raw();
 		cp_back(c);
-		return '\\';
+		return c_ec;
 	}
 	return c;
 }
@@ -87,7 +87,7 @@
 	if (in_top() >= 0)
 		return in_next();
 	c = cp_raw();
-	if (c == '\\') {
+	if (c == c_ec) {
 		c = cp_raw();
 		if (c == '"') {
 			while (c >= 0 && c != '\n')
@@ -106,7 +106,7 @@
 			c = cp_next();
 		} else {
 			cp_back(c);
-			c = '\\';
+			c = c_ec;
 		}
 	}
 	return c;
@@ -119,7 +119,7 @@
 	do {
 		c = skip ? cp_raw() : cp_next();
 	} while (c == ' ' || c == '\t');
-	if (c == '\\' && in_top() == '{') {	/* a troff \{ \} block */
+	if (c == c_ec && in_top() == '{') {	/* a troff \{ \} block */
 		if (skip) {
 			while (skip && cp_nblk > nblk && c >= 0)
 				c = cp_raw();
--- a/dev.c
+++ b/dev.c
@@ -125,9 +125,9 @@
 {
 	struct glyph *g;
 	int i;
-	if (c[0] == '\\' && c[1] == '\\')
+	if (c[0] == c_ec && c[1] == c_ec)
 		c++;
-	if (c[0] == '\\' && c[1] == '(')
+	if (c[0] == c_ec && c[1] == '(')
 		c += 2;
 	g = font_find(fn_font[fn], c);
 	if (g)
--- a/draw.c
+++ b/draw.c
@@ -35,7 +35,7 @@
 
 static int hchar(char *c)
 {
-	if (c[0] != '\\')
+	if (c[0] != c_ec)
 		return c[0] == '_';
 	if (c[1] != '(')
 		return c[1] == '_' || c[1] == '-';
@@ -45,7 +45,7 @@
 
 static int vchar(char *c)
 {
-	if (c[0] != '\\' || c[1] != '(')
+	if (c[0] != c_ec || c[1] != '(')
 		return c[0] == '_';
 	return (c[2] == 'b' && c[3] == 'v') || (c[2] == 'b' && c[3] == 'r');
 }
@@ -52,15 +52,15 @@
 
 void ren_hline(struct wb *wb, char *arg)
 {
-	char *lc = "\\(ru";
+	char lc[GNLEN] = {c_ec, '(', 'r', 'u'};
 	int w, l, n, i, rem;
 	l = eval_up(&arg, 'm');
 	if (!l)
 		return;
-	if (arg[0] == '\\' && arg[1] == '&')	/* \& can be used as a separator */
+	if (arg[0] == c_ec && arg[1] == '&')	/* \& can be used as a separator */
 		arg += 2;
 	if (*arg)
-		lc = arg;
+		strcpy(lc, arg);
 	w = cwid(lc);
 	/* negative length; moving backwards */
 	if (l < 0) {
@@ -93,16 +93,16 @@
 
 void ren_vline(struct wb *wb, char *arg)
 {
-	char *lc = "\\(br";
+	char lc[GNLEN] = {c_ec, '(', 'b', 'r'};
 	int w, l, n, i, rem, hw, neg;
 	l = eval_up(&arg, 'm');
 	if (!l)
 		return;
 	neg = l < 0;
-	if (arg[0] == '\\' && arg[1] == '&')	/* \& can be used as a separator */
+	if (arg[0] == c_ec && arg[1] == '&')	/* \& can be used as a separator */
 		arg += 2;
 	if (*arg)
-		lc = arg;
+		strcpy(lc, arg);
 	w = SC_HT;	/* character height */
 	hw = cwid(lc);		/* character width */
 	/* negative length; moving backwards */
--- a/in.c
+++ b/in.c
@@ -117,7 +117,7 @@
 	if (!buf)
 		return -1;
 	/* replacing \\ with \ only for buffers inserted via in_push() */
-	if (buf->buf[buf->pos] == '\\' && buf->buf[buf->pos + 1] == '\\')
+	if (buf->buf[buf->pos] == c_ec && buf->buf[buf->pos + 1] == c_ec)
 		buf->pos++;
 	return (unsigned char) buf->buf[buf->pos++];
 }
--- a/out.c
+++ b/out.c
@@ -164,12 +164,12 @@
 	char arg[ILNLEN];
 	while (*s) {
 		s = utf8get(c, s);
-		if (c[0] == '\\') {
+		if (c[0] == c_ec) {
 			s = utf8get(c + 1, s);
 			if (c[1] == '(') {
 				s = utf8get(c + 2, s);
 				s = utf8get(c + strlen(c), s);
-			} else if (c[1] == '\\') {
+			} else if (c[1] == c_ec) {
 				c[1] = '\0';
 			} else if (strchr("DfhsvX", c[1])) {
 				s = escarg(s, arg, c[1]);
@@ -203,7 +203,7 @@
 		if (utf8len(c[0]) == strlen(c))
 			outnn("c%s%s", c, c[1] ? "\n" : "");
 		else
-			out("C%s\n", c[0] == '\\' && c[1] == '(' ? c + 2 : c);
+			out("C%s\n", c[0] == c_ec && c[1] == '(' ? c + 2 : c);
 		outnn("h%d", charwid(g ? g->wid : SC_DW, o_s));
 	}
 }
--- a/ren.c
+++ b/ren.c
@@ -51,7 +51,7 @@
 		cdiv->treg = -1;
 		if (args[0][2] == 'a' && str_get(cdiv->reg))	/* .da */
 			sbuf_append(&cdiv->sbuf, str_get(cdiv->reg));
-		sbuf_append(&cdiv->sbuf, DIV_BEG "\n");
+		sbuf_printf(&cdiv->sbuf, "%c%s\n", c_cc, DIV_BEG);
 		cdiv->prev_d = n_d;
 		cdiv->prev_h = n_h;
 		cdiv->prev_mk = n_mk;
@@ -62,7 +62,7 @@
 		n_ns = 0;
 	} else if (cdiv) {
 		sbuf_putnl(&cdiv->sbuf);
-		sbuf_append(&cdiv->sbuf, DIV_END "\n");
+		sbuf_printf(&cdiv->sbuf, "%c%s\n", c_cc, DIV_END);
 		str_set(cdiv->reg, sbuf_buf(&cdiv->sbuf));
 		sbuf_done(&cdiv->sbuf);
 		n_dl = cdiv->dl;
@@ -143,7 +143,7 @@
 static void push_ne(void)
 {
 	char buf[32];
-	sprintf(buf, ".ne %du\n", n_p);
+	sprintf(buf, "%cne %du\n", c_cc, n_p);
 	in_pushnl(buf, NULL);
 }
 
@@ -203,7 +203,7 @@
 			cdiv->dl = w;
 		ljust += lt >= 0 ? lt : li;
 		if (ljust) {
-			sprintf(cmd, "\\h'%du'", ljust);
+			sprintf(cmd, "%ch'%du'", c_ec, ljust);
 			sbuf_append(&cdiv->sbuf, cmd);
 		}
 		sbuf_append(&cdiv->sbuf, s);
@@ -260,7 +260,7 @@
 
 void tr_br(char **args)
 {
-	if (args[0][0] == '.')
+	if (args[0][0] == c_cc)
 		ren_br(1);
 }
 
@@ -267,7 +267,7 @@
 void tr_sp(char **args)
 {
 	int traps = 0;
-	if (args[0][0] == '.')
+	if (args[0][0] == c_cc)
 		traps = ren_br(1);
 	if (!n_ns && !traps)
 		down(args[1] ? eval(args[1], 'v') : n_v);
@@ -324,11 +324,12 @@
 
 void tr_bp(char **args)
 {
+	char br[] = {c_cc, 'b', 'r', '\n'};
 	if (!cdiv && (args[1] || !n_ns)) {
 		if (!bp_force)
 			push_ne();
-		if (args[0][0] == '.')
-			in_pushnl(".br\n", NULL);
+		if (args[0][0] == c_cc)
+			in_pushnl(br, NULL);
 		bp_force = 1;
 		if (args[1])
 			bp_next = eval_re(args[1], n_pg, 0);
@@ -364,7 +365,7 @@
 void tr_in(char **args)
 {
 	int in = args[1] ? eval_re(args[1], n_i, 'm') : n_i0;
-	if (args[0][0] == '.')
+	if (args[0][0] == c_cc)
 		ren_br(1);
 	n_i0 = n_i;
 	n_i = MAX(0, in);
@@ -374,7 +375,7 @@
 
 void tr_ti(char **args)
 {
-	if (args[0][0] == '.')
+	if (args[0][0] == c_cc)
 		ren_br(1);
 	if (args[1])
 		adj_ti(cadj, eval_re(args[1], n_i, 'm'));
@@ -405,7 +406,7 @@
 
 void tr_nf(char **args)
 {
-	if (args[0][0] == '.')
+	if (args[0][0] == c_cc)
 		ren_br(1);
 	n_u = 0;
 }
@@ -412,7 +413,7 @@
 
 void tr_fi(char **args)
 {
-	if (args[0][0] == '.')
+	if (args[0][0] == c_cc)
 		ren_br(1);
 	n_u = 1;
 }
@@ -419,7 +420,7 @@
 
 void tr_ce(char **args)
 {
-	if (args[0][0] == '.')
+	if (args[0][0] == c_cc)
 		ren_br(1);
 	n_ce = args[1] ? atoi(args[1]) : 1;
 }
@@ -555,7 +556,7 @@
 		wb_put(wb, c);
 		return;
 	}
-	if (c[0] == '\\') {
+	if (c[0] == c_ec) {
 		nextchar(c + 1, next);
 		if (c[1] == '(') {
 			int l = nextchar(c + 2, next);
--- a/tr.c
+++ b/tr.c
@@ -6,6 +6,9 @@
 
 static int tr_nl = 1;
 static int c_pc = '%';		/* page number character */
+int c_ec = '\\';
+int c_cc = '.';
+int c_c2 = '\'';
 
 /* skip everything until the end of line */
 static void jmp_eol(void)
@@ -158,7 +161,7 @@
 {
 	d[0] = next();
 	d[1] = '\0';
-	if (d[0] == '\\') {
+	if (d[0] == c_ec) {
 		d[1] = next();
 		d[2] = '\0';
 		if (d[1] == '(') {
@@ -367,6 +370,26 @@
 	} while (c >= 0 && c != '\n');
 }
 
+static void tr_ec(char **args)
+{
+	c_ec = args[1] ? args[1][0] : '\\';
+}
+
+static void tr_cc(char **args)
+{
+	c_ec = args[1] ? args[1][0] : '.';
+}
+
+static void tr_c2(char **args)
+{
+	c_ec = args[1] ? args[1][0] : '\'';
+}
+
+static void tr_eo(char **args)
+{
+	c_ec = -1;
+}
+
 static char *arg_regname(char *s, int len)
 {
 	char *e = s + 2;
@@ -534,13 +557,15 @@
 	void (*f)(char **args);
 	int (*args)(char **args, char *buf, int len);
 } cmds[] = {
-	{DIV_BEG + 1, tr_divbeg},
-	{DIV_END + 1, tr_divend},
+	{DIV_BEG, tr_divbeg},
+	{DIV_END, tr_divend},
 	{"ad", tr_ad},
 	{"am", tr_de, mkargs_reg1},
 	{"as", tr_as, mkargs_ds},
 	{"bp", tr_bp},
 	{"br", tr_br},
+	{"c2", tr_c2},
+	{"cc", tr_cc},
 	{"ce", tr_ce},
 	{"ch", tr_ch},
 	{"da", tr_di},
@@ -548,7 +573,9 @@
 	{"di", tr_di},
 	{"ds", tr_ds, mkargs_ds},
 	{"dt", tr_dt},
+	{"ec", tr_ec},
 	{"el", tr_el, mkargs_null},
+	{"eo", tr_eo},
 	{"ev", tr_ev},
 	{"ex", tr_ex},
 	{"fi", tr_fi},
@@ -597,7 +624,7 @@
 	char cmd[RLEN];
 	char buf[LNLEN];
 	struct cmd *req;
-	while (tr_nl && (c == '.' || c == '\'')) {
+	while (tr_nl && (c == c_cc || c == c_c2)) {
 		nl = 1;
 		memset(args, 0, sizeof(args));
 		args[0] = cmd;
--- a/wb.c
+++ b/wb.c
@@ -27,11 +27,11 @@
 static void wb_font(struct wb *wb)
 {
 	if (wb->f != n_f) {
-		sbuf_printf(&wb->sbuf, "\\f(%02d", n_f);
+		sbuf_printf(&wb->sbuf, "%cf(%02d", c_ec, n_f);
 		wb->f = n_f;
 	}
 	if (wb->s != n_s) {
-		sbuf_printf(&wb->sbuf, "\\s(%02d", n_s);
+		sbuf_printf(&wb->sbuf, "%cs(%02d", c_ec, n_s);
 		wb->s = n_s;
 	}
 	wb_stsb(wb);
@@ -40,13 +40,13 @@
 void wb_hmov(struct wb *wb, int n)
 {
 	wb->h += n;
-	sbuf_printf(&wb->sbuf, "\\h'%du'", n);
+	sbuf_printf(&wb->sbuf, "%ch'%du'", c_ec, n);
 }
 
 void wb_vmov(struct wb *wb, int n)
 {
 	wb->v += n;
-	sbuf_printf(&wb->sbuf, "\\v'%du'", n);
+	sbuf_printf(&wb->sbuf, "%cv'%du'", c_ec, n);
 }
 
 void wb_els(struct wb *wb, int els)
@@ -60,7 +60,7 @@
 void wb_etc(struct wb *wb, char *x)
 {
 	wb_font(wb);
-	sbuf_printf(&wb->sbuf, "\\X%s", x);
+	sbuf_printf(&wb->sbuf, "%cX%s", c_ec, x);
 }
 
 void wb_put(struct wb *wb, char *c)
@@ -95,7 +95,7 @@
 void wb_drawl(struct wb *wb, int h, int v)
 {
 	wb_font(wb);
-	sbuf_printf(&wb->sbuf, "\\D'l %du %du'", h, v);
+	sbuf_printf(&wb->sbuf, "%cD'l %du %du'", c_ec, h, v);
 	wb->h += h;
 	wb->v += v;
 	wb_stsb(wb);
@@ -104,7 +104,7 @@
 void wb_drawc(struct wb *wb, int r)
 {
 	wb_font(wb);
-	sbuf_printf(&wb->sbuf, "\\D'c %du'", r);
+	sbuf_printf(&wb->sbuf, "%cD'c %du'", c_ec, r);
 	wb->h += r;
 }
 
@@ -111,7 +111,7 @@
 void wb_drawe(struct wb *wb, int h, int v)
 {
 	wb_font(wb);
-	sbuf_printf(&wb->sbuf, "\\D'e %du %du'", h, v);
+	sbuf_printf(&wb->sbuf, "%cD'e %du %du'", c_ec, h, v);
 	wb->h += h;
 }
 
@@ -118,7 +118,7 @@
 void wb_drawa(struct wb *wb, int h1, int v1, int h2, int v2)
 {
 	wb_font(wb);
-	sbuf_printf(&wb->sbuf, "\\D'a %du %du %du %du'", h1, v1, h2, v2);
+	sbuf_printf(&wb->sbuf, "%cD'a %du %du %du %du'", c_ec, h1, v1, h2, v2);
 	wb->h += h1 + h2;
 	wb->v += v1 + v2;
 	wb_stsb(wb);
@@ -127,7 +127,7 @@
 void wb_drawxbeg(struct wb *wb, int c)
 {
 	wb_font(wb);
-	sbuf_printf(&wb->sbuf, "\\D'%c", c);
+	sbuf_printf(&wb->sbuf, "%cD'%c", c_ec, c);
 }
 
 void wb_drawxdot(struct wb *wb, int h, int v)
--- a/xroff.h
+++ b/xroff.h
@@ -29,6 +29,11 @@
 #define MAX(a, b)	((a) < (b) ? (b) : (a))
 #define LEN(a)		(sizeof(a) / sizeof((a)[0]))
 
+/* special characters */
+extern int c_ec;	/* escape character (\) */
+extern int c_cc;	/* basic control character (.) */
+extern int c_c2;	/* no-break control character (') */
+
 /* number registers */
 int num_get(int id, int inc);
 void num_set(int id, int val);
@@ -244,8 +249,8 @@
 int schar_jump(char *d, int (*next)(void), void (*back)(int));
 
 /* diversions */
-#define DIV_BEG		".&<"
-#define DIV_END		".&>"
+#define DIV_BEG		"&<"
+#define DIV_END		"&>"
 
 /* builtin number registers; n_X for .X register */
 #define REG(c1, c2)	((c1) * 256 + (c2))