ref: 571b5fbddff6b434589db79ab6ae5df40033b925
parent: ced19dc8c75fc6adfcbea9a46f65bd38ddfef512
author: Ali Gholami Rudi <ali@rudi.ir>
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},
};