shithub: neatroff

Download patch

ref: 92b4c1ad20c7817371a32d40e563bed6b745a41f
parent: d7d272b68072acd84a344aa8351230c41edf311b
author: Ali Gholami Rudi <ali@rudi.ir>
date: Sat May 10 05:25:59 EDT 2014

fmt: specifying sentence space

This patch adds support for the second argument of .ss, as present
in Groff and Heirloom troff.

--- a/fmt.c
+++ b/fmt.c
@@ -18,7 +18,6 @@
 #define FMT_LLEN(f)	MAX(0, (f)->ll - (f)->li)
 #define FMT_FILL(f)	(!n_ce && n_u)
 #define FMT_ADJ(f)	(n_u && !n_na && !n_ce && (n_j & AD_B) == AD_B)
-#define FMT_SWID(f)	(spacewid(n_f, n_s))
 
 struct word {
 	char *s;
@@ -200,7 +199,7 @@
 
 void fmt_space(struct fmt *fmt)
 {
-	fmt->gap += FMT_SWID(fmt);
+	fmt->gap += N_SS(n_f, n_s);
 }
 
 int fmt_newline(struct fmt *f)
@@ -280,9 +279,11 @@
 /* the amount of space necessary before the next word */
 static int fmt_wordgap(struct fmt *f)
 {
-	if ((f->nls || f->nls_sup) && !f->gap && f->nwords >= 1)
-		return (f->nwords && f->eos) ? FMT_SWID(f) * 2 : FMT_SWID(f);
-	return f->gap;
+	int nls = f->nls || f->nls_sup;
+	if (f->eos && f->nwords)
+		if ((nls && !f->gap) || (!nls && f->gap == 2 * N_SS(n_f, n_s)))
+			return N_SS(n_f, n_s) + N_SSS(n_f, n_s);
+	return (nls && !f->gap && f->nwords) ? N_SS(n_f, n_s) : f->gap;
 }
 
 /* insert wb into fmt */
--- a/reg.c
+++ b/reg.c
@@ -36,7 +36,7 @@
 	".nS", ".m", ".s", ".u", ".v",
 	".it", ".itn", ".mc", ".mcn",
 	".ce", ".f0", ".hy", ".hyp", ".i0", ".l0",
-	".L0", ".m0", ".n0", ".s0", ".ss", ".ssh",
+	".L0", ".m0", ".n0", ".s0", ".ss", ".ssh", ".sss",
 	".ti", ".lt", ".lt0", ".v0",
 };
 
@@ -199,6 +199,7 @@
 		n_lt = SC_IN * 65 / 10;
 		n_hy = 1;
 		n_ss = 12;
+		n_sss = 12;
 		n_nM = 1;
 		n_nS = 1;
 		strcpy(env->hc, "\\%");
--- a/ren.c
+++ b/ren.c
@@ -93,11 +93,6 @@
 	return DEVWID(sz, wid) + (dev_getbd(fn) ? dev_getbd(fn) - 1 : 0);
 }
 
-int spacewid(int fn, int sz)
-{
-	return charwid(fn, sz, (dev_font(fn)->spacewid * n_ss + 6) / 12);
-}
-
 int f_divreg(void)
 {
 	return cdiv ? cdiv->reg : -1;
@@ -608,7 +603,7 @@
 {
 	switch (c) {
 	case ' ':
-		wb_hmov(wb, spacewid(n_f, n_s));
+		wb_hmov(wb, N_SS(n_f, n_s));
 		break;
 	case 'b':
 		ren_bcmd(wb, arg);
--- a/roff.h
+++ b/roff.h
@@ -181,10 +181,12 @@
 /* glyph handling functions */
 struct glyph *dev_glyph(char *c, int fn);
 int charwid(int fn, int sz, int wid);
-int spacewid(int fn, int sz);
 
 /* convert wid in device unitwidth size to size sz */
 #define DEVWID(sz, wid)		(((wid) * (sz) + (dev_uwid / 2)) / dev_uwid)
+/* the amount of word and sentence space for the given font and size */
+#define N_SS(fn, sz)	(charwid((fn), (sz), (dev_font(fn)->spacewid * n_ss + 6) / 12))
+#define N_SSS(fn, sz)	(charwid((fn), (sz), (dev_font(fn)->spacewid * n_sss + 6) / 12))
 
 /* different layers of neatroff */
 int in_next(void);		/* input layer */
@@ -467,8 +469,9 @@
 #define n_na		(*nreg(map(".na")))	/* .na mode */
 #define n_ns		(*nreg(map(".ns")))	/* .ns mode */
 #define n_o0		(*nreg(map(".o0")))	/* last .o */
-#define n_ss		(*nreg(map(".ss")))	/* .ss value */
-#define n_ssh		(*nreg(map(".ssh")))	/* .ssh value; word space compression */
+#define n_ss		(*nreg(map(".ss")))	/* word space (.ss) */
+#define n_sss		(*nreg(map(".sss")))	/* sentence space (.ss) */
+#define n_ssh		(*nreg(map(".ssh")))	/* word space compression (.ssh) */
 #define n_s0		(*nreg(map(".s0")))	/* last .s */
 #define n_sv		(*nreg(map(".sv")))	/* .sv value */
 #define n_lt		(*nreg(map(".lt")))	/* .lt value */
--- a/tr.c
+++ b/tr.c
@@ -420,8 +420,10 @@
 
 static void tr_ss(char **args)
 {
-	if (args[1])
+	if (args[1]) {
 		n_ss = eval_re(args[1], n_ss, 0);
+		n_sss = args[2] ? eval_re(args[2], n_sss, 0) : n_ss;
+	}
 }
 
 static void tr_ssh(char **args)
--- a/wb.c
+++ b/wb.c
@@ -169,7 +169,7 @@
 		return;
 	}
 	if (c[0] == ' ') {
-		wb_hmov(wb, spacewid(R_F(wb), R_S(wb)));
+		wb_hmov(wb, N_SS(R_F(wb), R_S(wb)));
 		return;
 	}
 	if (c[0] == '\t' || c[0] == '' ||