shithub: neatroff

Download patch

ref: d11408e98db95f4463e5c74cdab2ec1eeadaa0a9
parent: 78a59118aea99a388d678ba9bdd54b24322cc25c
author: Ali Gholami Rudi <ali@rudi.ir>
date: Tue Nov 20 17:09:20 EST 2012

extract out.c for printing troff code for a line

--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@
 all: xroff
 %.o: %.c xroff.h
 	$(CC) -c $(CFLAGS) $<
-xroff: xroff.o dev.o font.o in.o cp.o tr.o out.o reg.o
+xroff: xroff.o dev.o font.o in.o cp.o tr.o ren.o out.o reg.o
 	$(CC) -o $@ $^ $(LDFLAGS)
 clean:
 	rm -f *.o xroff
--- a/dev.c
+++ b/dev.c
@@ -175,3 +175,9 @@
 			return i;
 	return dev_mnt(0, id, id);
 }
+
+int charwid(int wid, int sz)
+{
+	/* the original troff rounds the widths up */
+	return (wid * sz + dev_uwid - 1) / dev_uwid;
+}
--- a/out.c
+++ b/out.c
@@ -4,22 +4,7 @@
 #include <string.h>
 #include "xroff.h"
 
-#define LINELEN		1024
-
-struct word {
-	int beg;	/* word beginning offset in buf */
-	int end;	/* word ending offset in buf */
-	int wid;	/* word width */
-	int blanks;	/* blanks before word */
-};
-
-static char buf[LINELEN];		/* output buffer */
-static int buflen;
-static struct word words[LINELEN];	/* words in the buffer */
-static int nwords;
-static int wid;				/* total width of the buffer */
-
-static int utf8len(int c)
+int utf8len(int c)
 {
 	if (c <= 0x7f)
 		return 1;
@@ -36,29 +21,6 @@
 	return 1;
 }
 
-static int out_next(void)
-{
-	int c = tr_next();
-	if (c < 0)
-		return -1;
-	buf[buflen++] = c;
-	return c;
-}
-
-static int nextchar(char *s)
-{
-	int c = out_next();
-	int l = utf8len(c);
-	int i;
-	if (c < 0)
-		return 0;
-	s[0] = c;
-	for (i = 1; i < l; i++)
-		s[i] = out_next();
-	s[l] = '\0';
-	return l;
-}
-
 static char *utf8get(char *d, char *s)
 {
 	int l = utf8len(*s);
@@ -69,15 +31,26 @@
 	return s + l;
 }
 
-static int charwid(int wid, int sz)
+static int o_s = 10;
+static int o_f = 1;
+
+static void out_ps(int n)
 {
-	/* the original troff rounds the widths up */
-	return (wid * sz + dev_uwid - 1) / dev_uwid;
+	if (o_s != n) {
+		o_s = n;
+		printf("s%d\n", o_s);
+	}
 }
 
-static int o_s, o_f;
+static void out_ft(int n)
+{
+	if (n >= 0 && o_f != n) {
+		o_f = n;
+		printf("f%d\n", o_f);
+	}
+}
 
-static char *read_escarg(char *s, char *d)
+static char *escarg(char *s, char *d)
 {
 	if (*s == '(') {
 		s++;
@@ -96,7 +69,7 @@
 	return s;
 }
 
-static void flush(char *s)
+void out_put(char *s)
 {
 	struct glyph *g;
 	char c[LLEN];
@@ -112,16 +85,13 @@
 				s = utf8get(c, s);
 				s = utf8get(c + strlen(c), s);
 			} else if (strchr("sf", c[0])) {
-				s = read_escarg(s, arg);
+				s = escarg(s, arg);
 				if (c[0] == 's') {
-					o_s = tr_int(arg, o_s, '\0');
-					printf("s%d\n", o_s);
+					out_ps(tr_int(arg, o_s, '\0'));
 					continue;
 				}
 				if (c[0] == 'f') {
-					o_f = dev_font(arg);
-					if (o_f >= 0)
-						printf("f%d\n", o_f);
+					out_ft(dev_font(arg));
 					continue;
 				}
 			}
@@ -141,175 +111,4 @@
 			o_blank = 1;
 		}
 	}
-}
-
-static void down(int n)
-{
-	printf("v%d\n", n);
-}
-
-static void adjust(char *s)
-{
-	struct word *last = words;
-	int w = 0;
-	int lendiff;
-	int i;
-	if (!nwords) {
-		s[0] = '\0';
-		return;
-	}
-	while (last < words + nwords && w + last->wid + last->blanks <= n_l) {
-		w += last->wid + last->blanks;
-		last++;
-	}
-	if (last > words)
-		last--;
-	memcpy(s, buf, last->end);
-	s[last->end] = '\0';
-	lendiff = last + 1 < words + nwords ? last[1].beg : buflen;
-	memmove(buf, buf + lendiff, buflen - lendiff);
-	buflen -= lendiff;
-	nwords -= last - words + 1;
-	memmove(words, last + 1, nwords * sizeof(words[0]));
-	wid -= w;
-	for (i = 0; i < nwords; i++) {
-		words[i].beg -= lendiff;
-		words[i].end -= lendiff;
-	}
-	if (nwords)
-		wid -= words[0].blanks;
-	words[0].blanks = 0;
-}
-
-void tr_br(int argc, char **args)
-{
-	char out[LINELEN];
-	buf[buflen] = '\0';
-	if (buflen) {
-		adjust(out);
-		flush(out);
-	}
-	o_s = n_s;
-	o_f = n_f;
-}
-
-void tr_sp(int argc, char **args)
-{
-	tr_br(0, NULL);
-	if (argc > 1)
-		down(tr_int(args[1], 0, 'v'));
-}
-
-static void out_ps(char *s)
-{
-	n_s = tr_int(s, n_s, '\0');
-}
-
-void tr_ps(int argc, char **args)
-{
-	if (argc >= 2)
-		out_ps(args[1]);
-	buflen += sprintf(buf + buflen, "\\s(%2d", n_s);
-}
-
-static int out_ft(char *name)
-{
-	int fn = dev_font(name);
-	if (fn >= 0)
-		n_f = fn;
-	return fn;
-}
-
-void tr_ft(int argc, char **args)
-{
-	int fn;
-	if (argc < 2)
-		return;
-	fn = out_ft(args[1]);
-	if (fn >= 0)
-		buflen += sprintf(buf + buflen, "\\f%d", n_f);
-}
-
-void tr_fp(int argc, char **args)
-{
-	if (argc < 3)
-		return;
-	if (dev_mnt(atoi(args[1]), args[2], argc > 3 ? args[3] : args[2]) < 0)
-		fprintf(stderr, "troff: failed to mount %s\n", args[2]);
-}
-
-static void escarg(char *s)
-{
-	int c;
-	c = out_next();
-	if (c == '(') {
-		*s++ = out_next();
-		*s++ = out_next();
-		*s = '\0';
-		return;
-	}
-	if (c == '\'') {
-		while (1) {
-			c = out_next();
-			if (c == '\'' || c < 0)
-				break;
-			*s++ = c;
-		}
-		*s = '\0';
-		return;
-	}
-	*s++ = c;
-	*s = '\0';
-}
-
-void render(void)
-{
-	char c[LLEN];
-	char arg[LINELEN];
-	struct glyph *g;
-	struct word *word = NULL;
-	int word_beg;
-	int blanks = 0;
-	tr_br(0, NULL);
-	while (nextchar(c) > 0) {
-		g = NULL;
-		word_beg = buflen - strlen(c);
-		if (c[0] == '\\') {
-			nextchar(c);
-			if (c[0] == '(') {
-				int l = nextchar(c);
-				l += nextchar(c + l);
-				c[l] = '\0';
-			} else if (strchr("sf", c[0])) {
-				escarg(arg);
-				if (c[0] == 'f')
-					out_ft(arg);
-				if (c[0] == 's')
-					out_ps(arg);
-				continue;
-			}
-		}
-		g = dev_glyph(c, n_f);
-		if (!g) {
-			blanks += charwid(dev_spacewid(), n_s);
-			word = NULL;
-			continue;
-		}
-		if (!word) {
-			word = &words[nwords++];
-			word->beg = word_beg;
-			word->wid = 0;
-			word->blanks = blanks;
-			wid += blanks;
-			blanks = 0;
-		}
-		word->end = buflen;
-		word->wid += charwid(g->wid, n_s);
-		wid += charwid(g->wid, n_s);
-		if (wid > n_l) {
-			word = NULL;
-			tr_br(0, NULL);
-		}
-	}
-	tr_br(0, NULL);
 }
--- /dev/null
+++ b/ren.c
@@ -1,0 +1,210 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "xroff.h"
+
+struct word {
+	int beg;	/* word beginning offset in buf */
+	int end;	/* word ending offset in buf */
+	int wid;	/* word width */
+	int blanks;	/* blanks before word */
+};
+
+static char buf[LINELEN];		/* output buffer */
+static int buflen;
+static struct word words[LINELEN];	/* words in the buffer */
+static int nwords;
+static int wid;				/* total width of the buffer */
+
+static int ren_next(void)
+{
+	int c = tr_next();
+	if (c < 0)
+		return -1;
+	buf[buflen++] = c;
+	return c;
+}
+
+static int nextchar(char *s)
+{
+	int c = ren_next();
+	int l = utf8len(c);
+	int i;
+	if (c < 0)
+		return 0;
+	s[0] = c;
+	for (i = 1; i < l; i++)
+		s[i] = ren_next();
+	s[l] = '\0';
+	return l;
+}
+
+static void down(int n)
+{
+	printf("v%d\n", n);
+}
+
+static void adjust(char *s)
+{
+	struct word *last = words;
+	int w = 0;
+	int lendiff;
+	int i;
+	if (!nwords) {
+		s[0] = '\0';
+		return;
+	}
+	while (last < words + nwords && w + last->wid + last->blanks <= n_l) {
+		w += last->wid + last->blanks;
+		last++;
+	}
+	if (last > words)
+		last--;
+	memcpy(s, buf, last->end);
+	s[last->end] = '\0';
+	lendiff = last + 1 < words + nwords ? last[1].beg : buflen;
+	memmove(buf, buf + lendiff, buflen - lendiff);
+	buflen -= lendiff;
+	nwords -= last - words + 1;
+	memmove(words, last + 1, nwords * sizeof(words[0]));
+	wid -= w;
+	for (i = 0; i < nwords; i++) {
+		words[i].beg -= lendiff;
+		words[i].end -= lendiff;
+	}
+	if (nwords)
+		wid -= words[0].blanks;
+	words[0].blanks = 0;
+}
+
+void tr_br(int argc, char **args)
+{
+	char out[LINELEN];
+	buf[buflen] = '\0';
+	if (buflen) {
+		adjust(out);
+		out_put(out);
+	}
+}
+
+void tr_sp(int argc, char **args)
+{
+	tr_br(0, NULL);
+	if (argc > 1)
+		down(tr_int(args[1], 0, 'v'));
+}
+
+static void ren_ps(char *s)
+{
+	n_s = tr_int(s, n_s, '\0');
+}
+
+void tr_ps(int argc, char **args)
+{
+	if (argc >= 2)
+		ren_ps(args[1]);
+	buflen += sprintf(buf + buflen, "\\s(%2d", n_s);
+}
+
+static int ren_ft(char *name)
+{
+	int fn = dev_font(name);
+	if (fn >= 0)
+		n_f = fn;
+	return fn;
+}
+
+void tr_ft(int argc, char **args)
+{
+	int fn;
+	if (argc < 2)
+		return;
+	fn = ren_ft(args[1]);
+	if (fn >= 0)
+		buflen += sprintf(buf + buflen, "\\f%d", n_f);
+}
+
+void tr_fp(int argc, char **args)
+{
+	if (argc < 3)
+		return;
+	if (dev_mnt(atoi(args[1]), args[2], argc > 3 ? args[3] : args[2]) < 0)
+		errmsg("troff: failed to mount %s\n", args[2]);
+}
+
+static void escarg(char *s)
+{
+	int c;
+	c = ren_next();
+	if (c == '(') {
+		*s++ = ren_next();
+		*s++ = ren_next();
+		*s = '\0';
+		return;
+	}
+	if (c == '\'') {
+		while (1) {
+			c = ren_next();
+			if (c == '\'' || c < 0)
+				break;
+			*s++ = c;
+		}
+		*s = '\0';
+		return;
+	}
+	*s++ = c;
+	*s = '\0';
+}
+
+void render(void)
+{
+	char c[LLEN];
+	char arg[LINELEN];
+	struct glyph *g;
+	struct word *word = NULL;
+	int word_beg;
+	int blanks = 0;
+	tr_br(0, NULL);
+	while (nextchar(c) > 0) {
+		g = NULL;
+		word_beg = buflen - strlen(c);
+		if (c[0] == '\\') {
+			nextchar(c);
+			if (c[0] == '(') {
+				int l = nextchar(c);
+				l += nextchar(c + l);
+				c[l] = '\0';
+			} else if (strchr("sf", c[0])) {
+				escarg(arg);
+				if (c[0] == 'f')
+					ren_ft(arg);
+				if (c[0] == 's')
+					ren_ps(arg);
+				continue;
+			}
+		}
+		g = dev_glyph(c, n_f);
+		if (!g) {
+			blanks += charwid(dev_spacewid(), n_s);
+			word = NULL;
+			continue;
+		}
+		if (!word) {
+			word = &words[nwords++];
+			word->beg = word_beg;
+			word->wid = 0;
+			word->blanks = blanks;
+			wid += blanks;
+			blanks = 0;
+		}
+		word->end = buflen;
+		word->wid += charwid(g->wid, n_s);
+		wid += charwid(g->wid, n_s);
+		if (wid > n_l) {
+			word = NULL;
+			tr_br(0, NULL);
+		}
+	}
+	tr_br(0, NULL);
+}
--- a/xroff.c
+++ b/xroff.c
@@ -1,3 +1,4 @@
+#include <stdarg.h>
 #include <stdio.h>
 #include "xroff.h"
 
@@ -22,9 +23,12 @@
 	printf("V%d\n", n_p);
 }
 
-void errmsg(char *msg)
+void errmsg(char *fmt, ...)
 {
-	fprintf(stderr, "%s", msg);
+	va_list ap;
+	va_start(ap, fmt);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
 }
 
 int main(void)
--- a/xroff.h
+++ b/xroff.h
@@ -76,10 +76,8 @@
 
 /* rendering */
 void render(void);
+void out_put(char *s);
 
-/* error messages */
-void errmsg(char *msg);
-
 /* troff commands */
 void tr_br(int argc, char **args);
 void tr_sp(int argc, char **args);
@@ -87,3 +85,8 @@
 void tr_ps(int argc, char **args);
 void tr_ft(int argc, char **args);
 void tr_fp(int argc, char **args);
+
+/* helpers */
+void errmsg(char *msg, ...);
+int utf8len(int c);
+int charwid(int wid, int sz);