shithub: neatroff

Download patch

ref: 571b5fbddff6b434589db79ab6ae5df40033b925
parent: ced19dc8c75fc6adfcbea9a46f65bd38ddfef512
author: Ali Gholami Rudi <[email protected]>
date: Fri Aug 16 19:49:47 EDT 2013

tr: add .tr

--- a/dev.c
+++ b/dev.c
@@ -129,6 +129,7 @@
 		c++;
 	if (c[0] == c_ec && c[1] == '(')
 		c += 2;
+	c = tr_map(c);
 	g = font_find(fn_font[fn], c);
 	if (g)
 		return g;
--- a/out.c
+++ b/out.c
@@ -248,7 +248,7 @@
 			}
 			if (c[0] == '\t' || c[0] == '' || !strcmp(c_hc, c))
 				continue;
-			outc(c);
+			outc(tr_map(c));
 			continue;
 		}
 		switch (t) {
--- a/roff.h
+++ b/roff.h
@@ -24,6 +24,7 @@
 #define NTRAPS		1024	/* number of traps per page */
 #define NIES		128	/* number of nested .ie commands */
 #define NTABS		16	/* number of tab stops */
+#define NTR		512	/* number of character translations (.tr) */
 #define NFIELDS		32	/* number of fields */
 #define MAXFRAC		100000	/* maximum value of the fractional part */
 #define LIGLEN		4	/* length of ligatures */
@@ -170,6 +171,10 @@
 void cp_wid(int enable);	/* control inlining \w requests */
 #define cp_back		in_back	/* cp.c is stateless */
 void tr_first(void);		/* read until the first non-command line */
+
+/* character translation (.tr) */
+void tr_add(char *c1, char *c2);
+char *tr_map(char *c);
 
 /* variable length string buffer */
 struct sbuf {
--- a/tr.c
+++ b/tr.c
@@ -518,6 +518,52 @@
 		in_lf(args[2], eval(args[1], 0));
 }
 
+/* character translation */
+static char tr_src[NTR][GNLEN];
+static char tr_dst[NTR][GNLEN];
+static int tr_n;
+
+static int tr_find(char *c)
+{
+	int i;
+	for (i = 0; i < tr_n; i++)
+		if (!strcmp(c, tr_src[i]))
+			return i;
+	return -1;
+}
+
+void tr_add(char *c1, char *c2)
+{
+	int i = tr_find(c1);
+	if (i < 0 && tr_n < NTR)
+		i = tr_n++;
+	if (i >= 0) {
+		strcpy(tr_src[i], c1);
+		strcpy(tr_dst[i], c2);
+	}
+}
+
+char *tr_map(char *c)
+{
+	int i = tr_find(c);
+	return i >= 0 ? tr_dst[i] : c;
+}
+
+static void tr_tr(char **args)
+{
+	char *s = args[1];
+	char c1[GNLEN], c2[GNLEN];
+	if (!s)
+		return;
+	while (*s) {
+		utf8read(&s, c1);
+		strcpy(c2, " ");
+		if (*s)
+			utf8read(&s, c2);
+		tr_add(c1, c2);
+	}
+}
+
 static char *arg_regname(char *s, int len)
 {
 	char *e = n_cp ? s + 2 : s + len;
@@ -764,6 +810,7 @@
 	{"ti", tr_ti},
 	{"tl", tr_tl, mkargs_null},
 	{"tm", tr_tm, mkargs_eol},
+	{"tr", tr_tr, mkargs_eol},
 	{"vs", tr_vs},
 	{"wh", tr_wh},
 };