X-Git-Url: https://git.cameronkatri.com/mandoc.git/blobdiff_plain/41c0c172fa779a830e564f1257bee34c155ba2d0..0236a2d85af70886c7725a1f28a04ad4216a5d4d:/man_term.c?ds=sidebyside

diff --git a/man_term.c b/man_term.c
index 0f6b4c03..c7cbea88 100644
--- a/man_term.c
+++ b/man_term.c
@@ -1,6 +1,6 @@
-/*	$Id: man_term.c,v 1.67 2010/05/15 20:51:40 kristaps Exp $ */
+/*	$Id: man_term.c,v 1.84 2010/07/23 13:22:35 kristaps Exp $ */
 /*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "mandoc.h"
 #include "out.h"
 #include "man.h"
 #include "term.h"
@@ -69,15 +70,13 @@ struct	termact {
 #define	MAN_NOTEXT	 (1 << 0) /* Never has text children. */
 };
 
-static	int		  a2width(const struct man_node *);
-static	int		  a2height(const struct man_node *);
+static	int		  a2width(const struct termp *, const char *);
+static	size_t		  a2height(const struct termp *, const char *);
 
-static	void		  print_man_head(struct termp *, 
-				const struct man_meta *);
 static	void		  print_man_nodelist(DECL_ARGS);
 static	void		  print_man_node(DECL_ARGS);
-static	void		  print_man_foot(struct termp *, 
-				const struct man_meta *);
+static	void		  print_man_head(struct termp *, const void *);
+static	void		  print_man_foot(struct termp *, const void *);
 static	void		  print_bvspace(struct termp *, 
 				const struct man_node *);
 
@@ -93,10 +92,9 @@ static	int		  pre_RS(DECL_ARGS);
 static	int		  pre_SH(DECL_ARGS);
 static	int		  pre_SS(DECL_ARGS);
 static	int		  pre_TP(DECL_ARGS);
-static	int		  pre_br(DECL_ARGS);
-static	int		  pre_fi(DECL_ARGS);
 static	int		  pre_ign(DECL_ARGS);
-static	int		  pre_nf(DECL_ARGS);
+static	int		  pre_in(DECL_ARGS);
+static	int		  pre_literal(DECL_ARGS);
 static	int		  pre_sp(DECL_ARGS);
 
 static	void		  post_IP(DECL_ARGS);
@@ -107,7 +105,7 @@ static	void		  post_SS(DECL_ARGS);
 static	void		  post_TP(DECL_ARGS);
 
 static	const struct termact termacts[MAN_MAX] = {
-	{ pre_br, NULL, MAN_NOTEXT }, /* br */
+	{ pre_sp, NULL, MAN_NOTEXT }, /* br */
 	{ NULL, NULL, 0 }, /* TH */
 	{ pre_SH, post_SH, 0 }, /* SH */
 	{ pre_SS, post_SS, 0 }, /* SS */
@@ -131,8 +129,8 @@ static	const struct termact termacts[MAN_MAX] = {
 	{ NULL, NULL, MAN_NOTEXT }, /* na */
 	{ pre_I, NULL, 0 }, /* i */
 	{ pre_sp, NULL, MAN_NOTEXT }, /* sp */
-	{ pre_nf, NULL, 0 }, /* nf */
-	{ pre_fi, NULL, 0 }, /* fi */
+	{ pre_literal, NULL, 0 }, /* nf */
+	{ pre_literal, NULL, 0 }, /* fi */
 	{ NULL, NULL, 0 }, /* r */
 	{ NULL, NULL, 0 }, /* RE */
 	{ pre_RS, post_RS, 0 }, /* RS */
@@ -140,13 +138,10 @@ static	const struct termact termacts[MAN_MAX] = {
 	{ pre_ign, NULL, 0 }, /* UC */
 	{ pre_ign, NULL, 0 }, /* PD */
  	{ pre_sp, NULL, MAN_NOTEXT }, /* Sp */
- 	{ pre_nf, NULL, 0 }, /* Vb */
- 	{ pre_fi, NULL, 0 }, /* Ve */
- 	{ pre_ign, NULL, MAN_NOTEXT }, /* de */
- 	{ pre_ign, NULL, MAN_NOTEXT }, /* dei */
- 	{ pre_ign, NULL, MAN_NOTEXT }, /* am */
- 	{ pre_ign, NULL, MAN_NOTEXT }, /* ami */
- 	{ NULL, NULL, 0 }, /* . */
+ 	{ pre_literal, NULL, 0 }, /* Vb */
+ 	{ pre_literal, NULL, 0 }, /* Ve */
+	{ pre_ign, NULL, 0 }, /* AT */
+	{ pre_in, NULL, MAN_NOTEXT }, /* in */
 };
 
 
@@ -163,6 +158,7 @@ terminal_man(void *arg, const struct man *man)
 
 	p->overstep = 0;
 	p->maxrmargin = p->defrmargin;
+	p->tabwidth = term_len(p, 5);
 
 	if (NULL == p->symtab)
 		switch (p->enc) {
@@ -177,44 +173,41 @@ terminal_man(void *arg, const struct man *man)
 	n = man_node(man);
 	m = man_meta(man);
 
-	print_man_head(p, m);
+	term_begin(p, print_man_head, print_man_foot, m);
 	p->flags |= TERMP_NOSPACE;
 
 	mt.fl = 0;
-	mt.lmargin = INDENT;
-	mt.offset = INDENT;
+	mt.lmargin = term_len(p, INDENT);
+	mt.offset = term_len(p, INDENT);
 
 	if (n->child)
 		print_man_nodelist(p, &mt, n->child, m);
-	print_man_foot(p, m);
+
+	term_end(p);
 }
 
 
-static int
-a2height(const struct man_node *n)
+static size_t
+a2height(const struct termp *p, const char *cp)
 {
 	struct roffsu	 su;
 
-	assert(MAN_TEXT == n->type);
-	assert(n->string);
-	if ( ! a2roffsu(n->string, &su, SCALE_VS))
-		SCALE_VS_INIT(&su, strlen(n->string));
+	if ( ! a2roffsu(cp, &su, SCALE_VS))
+		SCALE_VS_INIT(&su, term_strlen(p, cp));
 
-	return((int)term_vspan(&su));
+	return(term_vspan(p, &su));
 }
 
 
 static int
-a2width(const struct man_node *n)
+a2width(const struct termp *p, const char *cp)
 {
 	struct roffsu	 su;
 
-	assert(MAN_TEXT == n->type);
-	assert(n->string);
-	if ( ! a2roffsu(n->string, &su, SCALE_BU))
+	if ( ! a2roffsu(cp, &su, SCALE_BU))
 		return(-1);
 
-	return((int)term_hspan(&su));
+	return((int)term_hspan(p, &su));
 }
 
 
@@ -256,23 +249,25 @@ pre_I(DECL_ARGS)
 
 /* ARGSUSED */
 static int
-pre_fi(DECL_ARGS)
+pre_literal(DECL_ARGS)
 {
 
-	mt->fl &= ~MANT_LITERAL;
+	term_newln(p);
+	switch (n->tok) {
+	case (MAN_Vb):
+		/* FALLTHROUGH */
+	case (MAN_nf):
+		mt->fl |= MANT_LITERAL;
+		return(MAN_Vb != n->tok);
+	default:
+		mt->fl &= ~MANT_LITERAL;
+		break;
+	}
+
 	return(1);
 }
 
 
-/* ARGSUSED */
-static int
-pre_nf(DECL_ARGS)
-{
-
-	mt->fl |= MANT_LITERAL;
-	return(MAN_Vb != n->tok);
-}
-
 
 /* ARGSUSED */
 static int
@@ -360,16 +355,40 @@ pre_B(DECL_ARGS)
 
 /* ARGSUSED */
 static int
-pre_sp(DECL_ARGS)
+pre_in(DECL_ARGS)
 {
-	int		 i, len;
+	int		 len, less;
+	size_t		 v;
+	const char	*cp;
 
-	len = n->child ? a2height(n->child) : 1;
+	term_newln(p);
 
-	if (0 == len)
-		term_newln(p);
-	for (i = 0; i <= len; i++)
-		term_vspace(p);
+	if (NULL == n->child) {
+		p->offset = mt->offset;
+		return(0);
+	}
+
+	cp = n->child->string;
+	less = 0;
+
+	if ('-' == *cp)
+		less = -1;
+	else if ('+' == *cp)
+		less = 1;
+	else
+		cp--;
+
+	if ((len = a2width(p, ++cp)) < 0)
+		return(0);
+
+	v = (size_t)len;
+
+	if (less < 0)
+		p->offset -= p->offset > v ? v : p->offset;
+	else if (less > 0)
+		p->offset += v;
+	else 
+		p->offset = v;
 
 	return(0);
 }
@@ -377,10 +396,24 @@ pre_sp(DECL_ARGS)
 
 /* ARGSUSED */
 static int
-pre_br(DECL_ARGS)
+pre_sp(DECL_ARGS)
 {
+	size_t		 i, len;
+
+	switch (n->tok) {
+	case (MAN_br):
+		len = 0;
+		break;
+	default:
+		len = n->child ? a2height(p, n->child->string) : 1;
+		break;
+	}
+
+	if (0 == len)
+		term_newln(p);
+	for (i = 0; i < len; i++)
+		term_vspace(p);
 
-	term_newln(p);
 	return(0);
 }
 
@@ -411,11 +444,11 @@ pre_HP(DECL_ARGS)
 	/* Calculate offset. */
 
 	if (NULL != (nn = n->parent->head->child))
-		if ((ival = a2width(nn)) >= 0)
+		if ((ival = a2width(p, nn->string)) >= 0)
 			len = (size_t)ival;
 
 	if (0 == len)
-		len = 1;
+		len = term_len(p, 1);
 
 	p->offset = mt->offset;
 	p->rmargin = mt->offset + len;
@@ -456,7 +489,7 @@ pre_PP(DECL_ARGS)
 
 	switch (n->type) {
 	case (MAN_BLOCK):
-		mt->lmargin = INDENT;
+		mt->lmargin = term_len(p, INDENT);
 		print_bvspace(p, n);
 		break;
 	default:
@@ -500,7 +533,7 @@ pre_IP(DECL_ARGS)
 		if (NULL != (nn = nn->next)) {
 			for ( ; nn->next; nn = nn->next)
 				/* Do nothing. */ ;
-			if ((ival = a2width(nn)) >= 0)
+			if ((ival = a2width(p, nn->string)) >= 0)
 				len = (size_t)ival;
 		}
 
@@ -508,7 +541,7 @@ pre_IP(DECL_ARGS)
 	case (MAN_HEAD):
 		/* Handle zero-width lengths. */
 		if (0 == len)
-			len = 1;
+			len = term_len(p, 1);
 
 		p->offset = mt->offset;
 		p->rmargin = mt->offset + len;
@@ -588,7 +621,7 @@ pre_TP(DECL_ARGS)
 		while (nn && MAN_TEXT != nn->type)
 			nn = nn->next;
 		if (nn && nn->next)
-			if ((ival = a2width(nn)) >= 0)
+			if ((ival = a2width(p, nn->string)) >= 0)
 				len = (size_t)ival;
 	}
 
@@ -596,7 +629,7 @@ pre_TP(DECL_ARGS)
 	case (MAN_HEAD):
 		/* Handle zero-length properly. */
 		if (0 == len)
-			len = 1;
+			len = term_len(p, 1);
 
 		p->offset = mt->offset;
 		p->rmargin = mt->offset + len;
@@ -651,8 +684,8 @@ pre_SS(DECL_ARGS)
 
 	switch (n->type) {
 	case (MAN_BLOCK):
-		mt->lmargin = INDENT;
-		mt->offset = INDENT;
+		mt->lmargin = term_len(p, INDENT);
+		mt->offset = term_len(p, INDENT);
 		/* If following a prior empty `SS', no vspace. */
 		if (n->prev && MAN_SS == n->prev->tok)
 			if (NULL == n->prev->body->child)
@@ -663,7 +696,7 @@ pre_SS(DECL_ARGS)
 		break;
 	case (MAN_HEAD):
 		term_fontrepl(p, TERMFONT_BOLD);
-		p->offset = HALFINDENT;
+		p->offset = term_len(p, HALFINDENT);
 		break;
 	case (MAN_BODY):
 		p->offset = mt->offset;
@@ -701,8 +734,8 @@ pre_SH(DECL_ARGS)
 
 	switch (n->type) {
 	case (MAN_BLOCK):
-		mt->lmargin = INDENT;
-		mt->offset = INDENT;
+		mt->lmargin = term_len(p, INDENT);
+		mt->offset = term_len(p, INDENT);
 		/* If following a prior empty `SH', no vspace. */
 		if (n->prev && MAN_SH == n->prev->tok)
 			if (NULL == n->prev->body->child)
@@ -763,15 +796,15 @@ pre_RS(DECL_ARGS)
 	}
 
 	if (NULL == (nn = n->parent->head->child)) {
-		mt->offset = mt->lmargin + INDENT;
+		mt->offset = mt->lmargin + term_len(p, INDENT);
 		p->offset = mt->offset;
 		return(1);
 	}
 
-	if ((ival = a2width(nn)) < 0)
+	if ((ival = a2width(p, nn->string)) < 0)
 		return(1);
 
-	mt->offset = INDENT + (size_t)ival;
+	mt->offset = term_len(p, INDENT) + (size_t)ival;
 	p->offset = mt->offset;
 
 	return(1);
@@ -785,13 +818,13 @@ post_RS(DECL_ARGS)
 
 	switch (n->type) {
 	case (MAN_BLOCK):
-		mt->offset = mt->lmargin = INDENT;
+		mt->offset = mt->lmargin = term_len(p, INDENT);
 		break;
 	case (MAN_HEAD):
 		break;
 	default:
 		term_newln(p);
-		p->offset = INDENT;
+		p->offset = term_len(p, INDENT);
 		break;
 	}
 }
@@ -861,18 +894,26 @@ print_man_nodelist(DECL_ARGS)
 
 
 static void
-print_man_foot(struct termp *p, const struct man_meta *meta)
+print_man_foot(struct termp *p, const void *arg)
 {
 	char		buf[DATESIZ];
+	const struct man_meta *meta;
+
+	meta = (const struct man_meta *)arg;
 
 	term_fontrepl(p, TERMFONT_NONE);
 
-	time2a(meta->date, buf, DATESIZ);
+	if (meta->rawdate)
+		strlcpy(buf, meta->rawdate, DATESIZ);
+	else
+		time2a(meta->date, buf, DATESIZ);
 
 	term_vspace(p);
+	term_vspace(p);
+	term_vspace(p);
 
 	p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
-	p->rmargin = p->maxrmargin - strlen(buf);
+	p->rmargin = p->maxrmargin - term_strlen(p, buf);
 	p->offset = 0;
 
 	if (meta->source)
@@ -892,10 +933,13 @@ print_man_foot(struct termp *p, const struct man_meta *meta)
 
 
 static void
-print_man_head(struct termp *p, const struct man_meta *m)
+print_man_head(struct termp *p, const void *arg)
 {
 	char		buf[BUFSIZ], title[BUFSIZ];
 	size_t		buflen, titlen;
+	const struct man_meta *m;
+
+	m = (const struct man_meta *)arg;
 
 	/*
 	 * Note that old groff would spit out some spaces before the
@@ -910,14 +954,15 @@ print_man_head(struct termp *p, const struct man_meta *m)
 
 	if (m->vol)
 		strlcpy(buf, m->vol, BUFSIZ);
-	buflen = strlen(buf);
+	buflen = term_strlen(p, buf);
 
 	snprintf(title, BUFSIZ, "%s(%s)", m->title, m->msec);
-	titlen = strlen(title);
+	titlen = term_strlen(p, title);
 
 	p->offset = 0;
 	p->rmargin = 2 * (titlen+1) + buflen < p->maxrmargin ?
-	    (p->maxrmargin - strlen(buf) + 1) / 2 :
+	    (p->maxrmargin - 
+	     term_strlen(p, buf) + term_len(p, 1)) / 2 :
 	    p->maxrmargin - buflen;
 	p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;