shithub: neatroff

Download patch

ref: 96f78282dd2aa43bb8cc038cf15cfdf20cd598b9
parent: 8cd43423e4842210048f29e450ed339fbd17ea82
author: Ali Gholami Rudi <ali@rudi.ir>
date: Sun Dec 14 11:21:14 EST 2014

tr: .hydash and .hystop requests

The .hydash request specifies the list of characters after which words
may be broken (even when hyphenation is disabled) without inserting
hyphens.  Note that zero-width break point (\\:) is always in this
list.  The .hystop request specifies hyphenation inhibiting
characters.  Words containing any of the given characters are not
hyphenated, unless after dashes (characters specified via .hydash).

--- a/fmt.c
+++ b/fmt.c
@@ -267,7 +267,7 @@
 	word->wid = wb_wid(wb);
 	word->elsn = wb->els_neg;
 	word->elsp = wb->els_pos;
-	word->hy = hy ? wb_dashwid(wb) : 0;
+	word->hy = hy ? wb_hywid(wb) : 0;
 	word->str = str;
 	word->gap = gap;
 }
@@ -287,7 +287,7 @@
 			hyins[n] = 1;
 			hyidx[n++] = s - word;
 		}
-		if (!c && (!strcmp(c_bp, d) || c_dash(d))) {
+		if (!c && c_hydash(d)) {
 			hyins[n] = 0;
 			hyidx[n++] = s - word;
 		}
--- a/roff.h
+++ b/roff.h
@@ -42,7 +42,7 @@
 #define NCMAPS		512	/* number of character translations (.tr) */
 #define NSSTR		32	/* number of nested sstr_push() calls */
 #define NFIELDS		32	/* number of fields */
-#define NEOS		32	/* number of end of sentence characters */
+#define NCHARS		32	/* number of characters for .eos, .hydash, .hystop */
 #define MAXFRAC		100000	/* maximum value of the fractional part */
 #define NCDEFS		128	/* number of character definitions (.char) */
 #define NHYPHS		16384	/* hyphenation dictionary/patterns (.hw) */
@@ -268,10 +268,11 @@
 char *wb_buf(struct wb *wb);
 void wb_fnszget(struct wb *wb, int *fn, int *sz, int *m);
 void wb_fnszset(struct wb *wb, int fn, int sz, int m);
-int wb_dashwid(struct wb *wb);
-int c_dash(char *c);
+int wb_hywid(struct wb *wb);
 int c_eossent(char *s);
 int c_eostran(char *s);
+int c_hydash(char *s);
+int c_hystop(char *s);
 
 /* character translation (.tr) */
 void cmap_add(char *c1, char *c2);
--- a/tr.c
+++ b/tr.c
@@ -402,26 +402,26 @@
 }
 
 /* sentence ending and their transparent characters */
-static char eos_sentc[NEOS][GNLEN] = { ".", "?", "!", };
-static int eos_sents = 3;
-static char eos_tranc[NEOS][GNLEN] = { "'", "\"", ")", "]", "*", };
-static int eos_trans = 5;
+static char eos_sent[NCHARS][GNLEN] = { ".", "?", "!", };
+static int eos_sentcnt = 3;
+static char eos_tran[NCHARS][GNLEN] = { "'", "\"", ")", "]", "*", };
+static int eos_trancnt = 5;
 
 static void tr_eos(char **args)
 {
-	eos_sents = 0;
-	eos_trans = 0;
+	eos_sentcnt = 0;
+	eos_trancnt = 0;
 	if (args[1]) {
 		char *s = args[1];
-		while (s && charread(&s, eos_sentc[eos_sents]) >= 0)
-			if (eos_sents < NEOS - 1)
-				eos_sents++;
+		while (s && charread(&s, eos_sent[eos_sentcnt]) >= 0)
+			if (eos_sentcnt < NCHARS - 1)
+				eos_sentcnt++;
 	}
 	if (args[2]) {
 		char *s = args[2];
-		while (s && charread(&s, eos_tranc[eos_trans]) >= 0)
-			if (eos_trans < NEOS - 1)
-				eos_trans++;
+		while (s && charread(&s, eos_tran[eos_trancnt]) >= 0)
+			if (eos_trancnt < NCHARS - 1)
+				eos_trancnt++;
 	}
 }
 
@@ -428,8 +428,8 @@
 int c_eossent(char *s)
 {
 	int i;
-	for (i = 0; i < eos_sents; i++)
-		if (!strcmp(eos_sentc[i], s))
+	for (i = 0; i < eos_sentcnt; i++)
+		if (!strcmp(eos_sent[i], s))
 			return 1;
 	return 0;
 }
@@ -437,12 +437,18 @@
 int c_eostran(char *s)
 {
 	int i;
-	for (i = 0; i < eos_trans; i++)
-		if (!strcmp(eos_tranc[i], s))
+	for (i = 0; i < eos_trancnt; i++)
+		if (!strcmp(eos_tran[i], s))
 			return 1;
 	return 0;
 }
 
+/* hyphenation dashes and hyphenation inhibiting character */
+static char hy_dash[NCHARS][GNLEN] = { c_bp, "-", "em", "en", "\\-", "--", "hy", };
+static int hy_dashcnt = 7;
+static char hy_stop[NCHARS][GNLEN];
+static int hy_stopcnt = 0;
+
 static void tr_nh(char **args)
 {
 	n_hy = 0;
@@ -458,6 +464,46 @@
 	n_hycost = args[1] ? eval_re(args[1], n_hycost, '\0') : 0;
 }
 
+static void tr_hydash(char **args)
+{
+	hy_dashcnt = 1;		/* c_bp should always be present */
+	if (args[1]) {
+		char *s = args[1];
+		while (s && charread(&s, hy_dash[hy_dashcnt]) >= 0)
+			if (hy_dashcnt < NCHARS - 1)
+				hy_dashcnt++;
+	}
+}
+
+static void tr_hystop(char **args)
+{
+	hy_stopcnt = 0;
+	if (args[1]) {
+		char *s = args[1];
+		while (s && charread(&s, hy_stop[hy_stopcnt]) >= 0)
+			if (hy_stopcnt < NCHARS - 1)
+				hy_stopcnt++;
+	}
+}
+
+int c_hydash(char *s)
+{
+	int i;
+	for (i = 0; i < hy_dashcnt; i++)
+		if (!strcmp(hy_dash[i], s))
+			return 1;
+	return 0;
+}
+
+int c_hystop(char *s)
+{
+	int i;
+	for (i = 0; i < hy_stopcnt; i++)
+		if (!strcmp(hy_stop[i], s))
+			return 1;
+	return 0;
+}
+
 static void tr_pmll(char **args)
 {
 	n_pmll = args[1] ? eval_re(args[1], n_pmll, '\0') : 0;
@@ -954,6 +1000,8 @@
 	{"hpfa", tr_hpfa},
 	{"hy", tr_hy},
 	{"hycost", tr_hycost},
+	{"hydash", tr_hydash},
+	{"hystop", tr_hystop},
 	{"hw", tr_hw},
 	{"ie", tr_if, mkargs_null},
 	{"if", tr_if, mkargs_null},
--- a/wb.c
+++ b/wb.c
@@ -159,11 +159,6 @@
 	}
 }
 
-int c_dash(char *c)
-{
-	return !strcmp("-", c) || !strcmp("em", c) || !strcmp("hy", c);
-}
-
 /* return nonzero if it cannot be hyphenated */
 static int wb_hyph(char src[][GNLEN], int src_n, char *src_hyph, int flg)
 {
@@ -177,7 +172,7 @@
 	for (i = 0; i < src_n; i++) {
 		s = src[i];
 		smap[i] = d - word;
-		if (c_dash(s) || !strcmp(c_hc, s))
+		if (c_hystop(s))
 			return 1;
 		if (!strcmp(c_bp, s))
 			continue;
@@ -502,7 +497,7 @@
 }
 
 /* return the size of \(hy if appended to wb */
-int wb_dashwid(struct wb *wb)
+int wb_hywid(struct wb *wb)
 {
 	struct glyph *g = dev_glyph("hy", wb->f);
 	return g ? font_gwid(g->font, dev_font(wb->f), wb->s, g->wid) : 0;