shithub: neatroff

Download patch

ref: 037f40d88f7f3f0c8ac5645cd2a4979f8ef98778
parent: 888606f23b59720a5e76500b8681caf34c2c60c8
author: Ali Gholami Rudi <ali@rudi.ir>
date: Thu Oct 24 09:02:33 EDT 2013

tr: add .ochar to define a characters for a font

--- a/ren.c
+++ b/ren.c
@@ -730,7 +730,7 @@
 			strcpy(c, g ? g->name : "cnull");
 		}
 	}
-	if (!ren_div && cdef_map(c)) {			/* .char characters */
+	if (!ren_div && cdef_map(c, n_f)) {		/* .char characters */
 		wb_putexpand(wb, c);
 		return;
 	}
--- a/roff.h
+++ b/roff.h
@@ -241,8 +241,8 @@
 void cmap_add(char *c1, char *c2);
 char *cmap_map(char *c);
 /* character definition (.char) */
-char *cdef_map(char *c);
-int cdef_expand(struct wb *wb, char *c);
+char *cdef_map(char *c, int fn);
+int cdef_expand(struct wb *wb, char *c, int fn);
 
 /* hyphenation flags */
 #define HY_MASK		0x0f	/* enable hyphenation */
--- a/tr.c
+++ b/tr.c
@@ -556,28 +556,30 @@
 /* character definition (.char) */
 static char cdef_src[NCDEFS][GNLEN];	/* source character */
 static char *cdef_dst[NCDEFS];		/* character definition */
+static char cdef_fn[NCDEFS][FNLEN];	/* owning font */
 static int cdef_n;			/* number of defined characters */
 static int cdef_expanding;		/* inside cdef_expand() call */
 
-static int cdef_find(char *c)
+static int cdef_find(char *c, int fn)
 {
 	int i;
 	for (i = 0; i < cdef_n; i++)
-		if (!strcmp(cdef_src[i], c))
+		if (!strcmp(cdef_src[i], c) &&
+				(!cdef_fn[i][0] || dev_pos(cdef_fn[i]) == fn))
 			return i;
 	return -1;
 }
 
 /* return the definition of the given character */
-char *cdef_map(char *c)
+char *cdef_map(char *c, int fn)
 {
-	int i = cdef_find(c);
+	int i = cdef_find(c, fn);
 	return !cdef_expanding && i >= 0 ? cdef_dst[i] : NULL;
 }
 
-int cdef_expand(struct wb *wb, char *s)
+int cdef_expand(struct wb *wb, char *s, int fn)
 {
-	char *d = cdef_map(s);
+	char *d = cdef_map(s, fn);
 	if (!d)
 		return 1;
 	cdef_expanding = 1;
@@ -586,39 +588,57 @@
 	return 0;
 }
 
-static void tr_char(char **args)
+static void cdef_add(char *fn, char *cs, char *def)
 {
 	char c[GNLEN];
-	char *s = args[1];
 	int i;
-	if (!args[2] || charread(&s, c) < 0)
+	if (!def || charread(&cs, c) < 0)
 		return;
-	i = cdef_find(c);
+	i = cdef_find(c, -1);
 	if (i < 0 && cdef_n < NCDEFS)
 		i = cdef_n++;
 	if (i >= 0) {
 		strncpy(cdef_src[i], c, sizeof(cdef_src[i]) - 1);
-		cdef_dst[i] = malloc(strlen(args[2]) + 1);
-		strcpy(cdef_dst[i], args[2]);
+		cdef_dst[i] = malloc(strlen(def) + 1);
+		strcpy(cdef_dst[i], def);
+		strcpy(cdef_fn[i], fn ? fn : "");
 	}
 }
 
-static void tr_rchar(char **args)
+static void cdef_remove(char *cs)
 {
 	char c[GNLEN];
-	char *s;
 	int i;
-	for (i = 1; i <= NARGS; i++) {
-		s = args[i];
-		if (s && charread(&s, c) >= 0) {
-			if (cdef_find(c) >= 0) {
-				free(cdef_dst[cdef_find(c)]);
-				cdef_dst[cdef_find(c)] = NULL;
-			}
+	if (!cs || charread(&cs, c) < 0)
+		return;
+	for (i = 0; i < cdef_n; i++) {
+		if (!strcmp(cdef_src[i], c)) {
+			free(cdef_dst[i]);
+			cdef_dst[i] = NULL;
+			cdef_src[i][0] = '\0';
+			cdef_fn[i][0] = '\0';
 		}
 	}
 }
 
+static void tr_char(char **args)
+{
+	cdef_add(NULL, args[1], args[2]);
+}
+
+static void tr_rchar(char **args)
+{
+	int i;
+	for (i = 1; i <= NARGS; i++)
+		if (args[i])
+			cdef_remove(args[i]);
+}
+
+static void tr_ochar(char **args)
+{
+	cdef_add(args[1], args[2], args[3]);
+}
+
 static char *arg_regname(char *s, int len)
 {
 	char *e = n_cp ? s + 2 : s + len;
@@ -799,6 +819,7 @@
 	{"br", tr_br},
 	{"c2", tr_c2},
 	{"cc", tr_cc},
+	{"ochar", tr_ochar},
 	{"ce", tr_ce},
 	{"ch", tr_ch},
 	{"char", tr_char, mkargs_ds},
--- a/wb.c
+++ b/wb.c
@@ -167,7 +167,7 @@
 /* just like wb_put(), but call cdef_expand() if c is defined */
 void wb_putexpand(struct wb *wb, char *c)
 {
-	if (cdef_expand(wb, c))
+	if (cdef_expand(wb, c, R_F(wb)))
 		wb_put(wb, c);
 }