shithub: neatroff

Download patch

ref: 9f993218e3755f088e2b75bde569652999e398b5
parent: 3e641e93f88d8d231ce283d9a72a703ee1736058
author: Ali Gholami Rudi <ali@rudi.ir>
date: Tue Nov 27 14:49:12 EST 2012

implement .bp

--- a/dev.c
+++ b/dev.c
@@ -28,8 +28,6 @@
 	printf("x T utf\n");
 	printf("x res %d %d %d\n", dev_res, dev_hor, dev_ver);
 	printf("x init\n");
-	printf("V0\n");
-	printf("p1\n");
 }
 
 int dev_mnt(int pos, char *id, char *name)
--- a/out.c
+++ b/out.c
@@ -78,8 +78,6 @@
 	struct glyph *g;
 	char c[GNLEN * 2];
 	char arg[ILNLEN];
-	printf("v%d\n", n_v);
-	printf("H%d\n", n_o + n_i);
 	while (*s) {
 		s = utf8get(c, s);
 		if (c[0] == '\\') {
--- a/ren.c
+++ b/ren.c
@@ -16,9 +16,8 @@
 static struct word words[NWORDS];	/* words in the buffer */
 static int nwords;
 static int wid;				/* total width of the buffer */
+static struct word *word;		/* current word */
 static int ren_backed = -1;		/* pushed back character */
-static int req_br;			/* pending .br request */
-static int req_sp;			/* pending .sp request */
 
 static int ren_next(void)
 {
@@ -90,18 +89,36 @@
 	words[0].blanks = 0;
 }
 
+static void ren_br(int sp, int adj);
+
 void tr_br(char **args)
 {
-	req_br = 1;
+	ren_br(0, 0);
 }
 
 void tr_sp(char **args)
 {
-	tr_br(NULL);
+	int sp = 0;
 	if (args[1])
-		req_sp = tr_int(args[1], 0, 'v');
+		sp = tr_int(args[1], 0, 'v');
+	ren_br(sp, 0);
 }
 
+void ren_page(int pg)
+{
+	n_nl = -1;
+	n_d = 0;
+	n_pg = pg;
+	printf("p%d\n", pg);
+	printf("V%d\n", 0);
+}
+
+void tr_bp(char **args)
+{
+	ren_br(0, 0);
+	ren_page(args[1] ? tr_int(args[1], n_pg, 'v') : n_pg + 1);
+}
+
 static void ren_ps(char *s)
 {
 	int ps = !*s || !strcmp("0", s) ? n_s0 : tr_int(s, n_s, '\0');
@@ -173,18 +190,25 @@
 	*s = '\0';
 }
 
-static void ren_br(int adj)
+static void down(int n)
 {
+	n_d += n;
+	n_nl = n_d;
+	printf("v%d\n", n);
+}
+
+static void ren_br(int sp, int adj)
+{
 	char out[LNLEN];
 	buf[buflen] = '\0';
 	if (nwords) {
-		adjust(out, adj);
+		adjust(out, wid > n_l ? n_ad : adj);
+		down(n_v);
+		printf("H%d\n", n_o + n_i);
 		output(out);
 	}
-	if (req_sp)
-		printf("v%d\n", req_sp);
-	req_br = 0;
-	req_sp = 0;
+	if (sp)
+		down(sp);
 }
 
 void render(void)
@@ -193,34 +217,37 @@
 	char arg[ILNLEN];
 	struct glyph *g;
 	int g_wid;
-	struct word *word = NULL;
 	int blanks = 0;
 	int newline = 0;
 	int r_s = n_s;
 	int r_f = n_f;
 	int esc = 0;
-	tr_br(NULL);
+	int space_br = 0;	/* .br caused by indented lines */
+	ren_br(0, 0);
 	while (nextchar(c) > 0) {
+		g = NULL;
+		if (!word && wid > n_l)
+			ren_br(0, wid > n_l ? n_ad : 0);
 		if (c[0] == ' ' || c[0] == '\n') {
 			if (word) {
 				word->end = buflen;
 				word = NULL;
 			}
-			if (newline)
-				req_br = 1;
 			if (newline && c[0] == '\n')
-				req_sp += n_v;
+				ren_br(n_v, 0);
+			if (newline && c[0] == ' ' && !space_br) {
+				space_br = 1;
+				ren_br(0, 0);
+			}
 			if (c[0] == '\n') {
 				blanks = 0;
 				newline = 1;
+				space_br = 0;
 			}
 			if (c[0] == ' ')
 				blanks += charwid(dev_spacewid(), n_s);
 			continue;
 		}
-		g = NULL;
-		if (!word && (wid > n_l || req_br))
-			ren_br(wid > n_l ? n_ad : 0);
 		esc = 0;
 		if (c[0] == '\\') {
 			esc = 1;
@@ -267,6 +294,6 @@
 		word->wid += g_wid;
 		wid += g_wid;
 	}
-	ren_br(wid > n_l ? n_ad : 0);
-	ren_br(0);
+	ren_br(0, wid > n_l ? n_ad : 0);
+	ren_br(0, 0);
 }
--- a/tr.c
+++ b/tr.c
@@ -260,6 +260,7 @@
 	void (*f)(char **args);
 	int (*args)(char **args, char *buf, int len);
 } cmds[] = {
+	{"bp", tr_bp},
 	{"br", tr_br},
 	{"de", tr_de, mkargs_reg1},
 	{"ds", tr_ds, mkargs_ds},
--- a/xroff.c
+++ b/xroff.c
@@ -27,8 +27,7 @@
 {
 	printf("s%d\n", n_s);
 	printf("f%d\n", n_f);
-	printf("H%d\n", n_o);
-	printf("V%d\n", 0);
+	ren_page(1);
 	render();
 	printf("V%d\n", n_p);
 }
--- a/xroff.h
+++ b/xroff.h
@@ -28,13 +28,16 @@
 
 /* builtin number registers; n_X for .X register */
 #define REG(c1, c2)	((c1) * 256 + (c2))
+#define n_d		nreg[REG('.', 'd')]
 #define n_f		nreg[REG('.', 'f')]
-#define n_s		nreg[REG('.', 's')]
+#define n_i		nreg[REG('.', 'i')]
+#define n_l		nreg[REG('.', 'l')]
 #define n_o		nreg[REG('.', 'o')]
 #define n_p		nreg[REG('.', 'p')]
-#define n_l		nreg[REG('.', 'l')]
+#define n_s		nreg[REG('.', 's')]
 #define n_v		nreg[REG('.', 'v')]
-#define n_i		nreg[REG('.', 'i')]
+#define n_nl		nreg[REG('n', 'l')]
+#define n_pg		nreg[REG('%', '\0')]	/* % */
 #define n_f0		nreg[REG('\0', 'f')]	/* last font */
 #define n_s0		nreg[REG('\0', 's')]	/* last size */
 #define n_ad		nreg[REG('\0', 'a')]	/* adjustment */
@@ -59,7 +62,7 @@
 	int nglyphs;
 	int spacewid;
 	int special;
-	char c[NGLYPHS][FNLEN];	/* character names in charset */
+	char c[NGLYPHS][FNLEN];		/* character names in charset */
 	struct glyph *g[NGLYPHS];	/* character glyphs in charset */
 	int n;				/* number of characters in charset */
 };
@@ -94,6 +97,7 @@
 /* rendering */
 void render(void);	/* read from in.c and print the output */
 void output(char *s);	/* output the given rendered line */
+void ren_page(int pg);
 
 /* troff commands */
 void tr_br(char **args);
@@ -102,6 +106,7 @@
 void tr_ps(char **args);
 void tr_ft(char **args);
 void tr_fp(char **args);
+void tr_bp(char **args);
 
 /* helpers */
 void errmsg(char *msg, ...);