xref: /titanic_51/usr/src/cmd/mandoc/man_term.c (revision 95c635efb7c3b86efc493e0447eaec7aecca3f0f)
1*95c635efSGarrett D'Amore /*	$Id: man_term.c,v 1.127 2012/01/03 15:16:24 kristaps Exp $ */
2*95c635efSGarrett D'Amore /*
3*95c635efSGarrett D'Amore  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
4*95c635efSGarrett D'Amore  * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
5*95c635efSGarrett D'Amore  *
6*95c635efSGarrett D'Amore  * Permission to use, copy, modify, and distribute this software for any
7*95c635efSGarrett D'Amore  * purpose with or without fee is hereby granted, provided that the above
8*95c635efSGarrett D'Amore  * copyright notice and this permission notice appear in all copies.
9*95c635efSGarrett D'Amore  *
10*95c635efSGarrett D'Amore  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11*95c635efSGarrett D'Amore  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12*95c635efSGarrett D'Amore  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13*95c635efSGarrett D'Amore  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14*95c635efSGarrett D'Amore  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15*95c635efSGarrett D'Amore  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16*95c635efSGarrett D'Amore  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*95c635efSGarrett D'Amore  */
18*95c635efSGarrett D'Amore #ifdef HAVE_CONFIG_H
19*95c635efSGarrett D'Amore #include "config.h"
20*95c635efSGarrett D'Amore #endif
21*95c635efSGarrett D'Amore 
22*95c635efSGarrett D'Amore #include <sys/types.h>
23*95c635efSGarrett D'Amore 
24*95c635efSGarrett D'Amore #include <assert.h>
25*95c635efSGarrett D'Amore #include <ctype.h>
26*95c635efSGarrett D'Amore #include <stdio.h>
27*95c635efSGarrett D'Amore #include <stdlib.h>
28*95c635efSGarrett D'Amore #include <string.h>
29*95c635efSGarrett D'Amore 
30*95c635efSGarrett D'Amore #include "mandoc.h"
31*95c635efSGarrett D'Amore #include "out.h"
32*95c635efSGarrett D'Amore #include "man.h"
33*95c635efSGarrett D'Amore #include "term.h"
34*95c635efSGarrett D'Amore #include "main.h"
35*95c635efSGarrett D'Amore 
36*95c635efSGarrett D'Amore #define	MAXMARGINS	  64 /* maximum number of indented scopes */
37*95c635efSGarrett D'Amore 
38*95c635efSGarrett D'Amore /* FIXME: have PD set the default vspace width. */
39*95c635efSGarrett D'Amore 
40*95c635efSGarrett D'Amore struct	mtermp {
41*95c635efSGarrett D'Amore 	int		  fl;
42*95c635efSGarrett D'Amore #define	MANT_LITERAL	 (1 << 0)
43*95c635efSGarrett D'Amore 	size_t		  lmargin[MAXMARGINS]; /* margins (incl. visible page) */
44*95c635efSGarrett D'Amore 	int		  lmargincur; /* index of current margin */
45*95c635efSGarrett D'Amore 	int		  lmarginsz; /* actual number of nested margins */
46*95c635efSGarrett D'Amore 	size_t		  offset; /* default offset to visible page */
47*95c635efSGarrett D'Amore };
48*95c635efSGarrett D'Amore 
49*95c635efSGarrett D'Amore #define	DECL_ARGS 	  struct termp *p, \
50*95c635efSGarrett D'Amore 			  struct mtermp *mt, \
51*95c635efSGarrett D'Amore 			  const struct man_node *n, \
52*95c635efSGarrett D'Amore 			  const struct man_meta *m
53*95c635efSGarrett D'Amore 
54*95c635efSGarrett D'Amore struct	termact {
55*95c635efSGarrett D'Amore 	int		(*pre)(DECL_ARGS);
56*95c635efSGarrett D'Amore 	void		(*post)(DECL_ARGS);
57*95c635efSGarrett D'Amore 	int		  flags;
58*95c635efSGarrett D'Amore #define	MAN_NOTEXT	 (1 << 0) /* Never has text children. */
59*95c635efSGarrett D'Amore };
60*95c635efSGarrett D'Amore 
61*95c635efSGarrett D'Amore static	int		  a2width(const struct termp *, const char *);
62*95c635efSGarrett D'Amore static	size_t		  a2height(const struct termp *, const char *);
63*95c635efSGarrett D'Amore 
64*95c635efSGarrett D'Amore static	void		  print_man_nodelist(DECL_ARGS);
65*95c635efSGarrett D'Amore static	void		  print_man_node(DECL_ARGS);
66*95c635efSGarrett D'Amore static	void		  print_man_head(struct termp *, const void *);
67*95c635efSGarrett D'Amore static	void		  print_man_foot(struct termp *, const void *);
68*95c635efSGarrett D'Amore static	void		  print_bvspace(struct termp *,
69*95c635efSGarrett D'Amore 				const struct man_node *);
70*95c635efSGarrett D'Amore 
71*95c635efSGarrett D'Amore static	int		  pre_B(DECL_ARGS);
72*95c635efSGarrett D'Amore static	int		  pre_HP(DECL_ARGS);
73*95c635efSGarrett D'Amore static	int		  pre_I(DECL_ARGS);
74*95c635efSGarrett D'Amore static	int		  pre_IP(DECL_ARGS);
75*95c635efSGarrett D'Amore static	int		  pre_OP(DECL_ARGS);
76*95c635efSGarrett D'Amore static	int		  pre_PP(DECL_ARGS);
77*95c635efSGarrett D'Amore static	int		  pre_RS(DECL_ARGS);
78*95c635efSGarrett D'Amore static	int		  pre_SH(DECL_ARGS);
79*95c635efSGarrett D'Amore static	int		  pre_SS(DECL_ARGS);
80*95c635efSGarrett D'Amore static	int		  pre_TP(DECL_ARGS);
81*95c635efSGarrett D'Amore static	int		  pre_alternate(DECL_ARGS);
82*95c635efSGarrett D'Amore static	int		  pre_ft(DECL_ARGS);
83*95c635efSGarrett D'Amore static	int		  pre_ign(DECL_ARGS);
84*95c635efSGarrett D'Amore static	int		  pre_in(DECL_ARGS);
85*95c635efSGarrett D'Amore static	int		  pre_literal(DECL_ARGS);
86*95c635efSGarrett D'Amore static	int		  pre_sp(DECL_ARGS);
87*95c635efSGarrett D'Amore 
88*95c635efSGarrett D'Amore static	void		  post_IP(DECL_ARGS);
89*95c635efSGarrett D'Amore static	void		  post_HP(DECL_ARGS);
90*95c635efSGarrett D'Amore static	void		  post_RS(DECL_ARGS);
91*95c635efSGarrett D'Amore static	void		  post_SH(DECL_ARGS);
92*95c635efSGarrett D'Amore static	void		  post_SS(DECL_ARGS);
93*95c635efSGarrett D'Amore static	void		  post_TP(DECL_ARGS);
94*95c635efSGarrett D'Amore 
95*95c635efSGarrett D'Amore static	const struct termact termacts[MAN_MAX] = {
96*95c635efSGarrett D'Amore 	{ pre_sp, NULL, MAN_NOTEXT }, /* br */
97*95c635efSGarrett D'Amore 	{ NULL, NULL, 0 }, /* TH */
98*95c635efSGarrett D'Amore 	{ pre_SH, post_SH, 0 }, /* SH */
99*95c635efSGarrett D'Amore 	{ pre_SS, post_SS, 0 }, /* SS */
100*95c635efSGarrett D'Amore 	{ pre_TP, post_TP, 0 }, /* TP */
101*95c635efSGarrett D'Amore 	{ pre_PP, NULL, 0 }, /* LP */
102*95c635efSGarrett D'Amore 	{ pre_PP, NULL, 0 }, /* PP */
103*95c635efSGarrett D'Amore 	{ pre_PP, NULL, 0 }, /* P */
104*95c635efSGarrett D'Amore 	{ pre_IP, post_IP, 0 }, /* IP */
105*95c635efSGarrett D'Amore 	{ pre_HP, post_HP, 0 }, /* HP */
106*95c635efSGarrett D'Amore 	{ NULL, NULL, 0 }, /* SM */
107*95c635efSGarrett D'Amore 	{ pre_B, NULL, 0 }, /* SB */
108*95c635efSGarrett D'Amore 	{ pre_alternate, NULL, 0 }, /* BI */
109*95c635efSGarrett D'Amore 	{ pre_alternate, NULL, 0 }, /* IB */
110*95c635efSGarrett D'Amore 	{ pre_alternate, NULL, 0 }, /* BR */
111*95c635efSGarrett D'Amore 	{ pre_alternate, NULL, 0 }, /* RB */
112*95c635efSGarrett D'Amore 	{ NULL, NULL, 0 }, /* R */
113*95c635efSGarrett D'Amore 	{ pre_B, NULL, 0 }, /* B */
114*95c635efSGarrett D'Amore 	{ pre_I, NULL, 0 }, /* I */
115*95c635efSGarrett D'Amore 	{ pre_alternate, NULL, 0 }, /* IR */
116*95c635efSGarrett D'Amore 	{ pre_alternate, NULL, 0 }, /* RI */
117*95c635efSGarrett D'Amore 	{ pre_ign, NULL, MAN_NOTEXT }, /* na */
118*95c635efSGarrett D'Amore 	{ pre_sp, NULL, MAN_NOTEXT }, /* sp */
119*95c635efSGarrett D'Amore 	{ pre_literal, NULL, 0 }, /* nf */
120*95c635efSGarrett D'Amore 	{ pre_literal, NULL, 0 }, /* fi */
121*95c635efSGarrett D'Amore 	{ NULL, NULL, 0 }, /* RE */
122*95c635efSGarrett D'Amore 	{ pre_RS, post_RS, 0 }, /* RS */
123*95c635efSGarrett D'Amore 	{ pre_ign, NULL, 0 }, /* DT */
124*95c635efSGarrett D'Amore 	{ pre_ign, NULL, 0 }, /* UC */
125*95c635efSGarrett D'Amore 	{ pre_ign, NULL, 0 }, /* PD */
126*95c635efSGarrett D'Amore 	{ pre_ign, NULL, 0 }, /* AT */
127*95c635efSGarrett D'Amore 	{ pre_in, NULL, MAN_NOTEXT }, /* in */
128*95c635efSGarrett D'Amore 	{ pre_ft, NULL, MAN_NOTEXT }, /* ft */
129*95c635efSGarrett D'Amore 	{ pre_OP, NULL, 0 }, /* OP */
130*95c635efSGarrett D'Amore };
131*95c635efSGarrett D'Amore 
132*95c635efSGarrett D'Amore 
133*95c635efSGarrett D'Amore 
134*95c635efSGarrett D'Amore void
135*95c635efSGarrett D'Amore terminal_man(void *arg, const struct man *man)
136*95c635efSGarrett D'Amore {
137*95c635efSGarrett D'Amore 	struct termp		*p;
138*95c635efSGarrett D'Amore 	const struct man_node	*n;
139*95c635efSGarrett D'Amore 	const struct man_meta	*m;
140*95c635efSGarrett D'Amore 	struct mtermp		 mt;
141*95c635efSGarrett D'Amore 
142*95c635efSGarrett D'Amore 	p = (struct termp *)arg;
143*95c635efSGarrett D'Amore 
144*95c635efSGarrett D'Amore 	if (0 == p->defindent)
145*95c635efSGarrett D'Amore 		p->defindent = 7;
146*95c635efSGarrett D'Amore 
147*95c635efSGarrett D'Amore 	p->overstep = 0;
148*95c635efSGarrett D'Amore 	p->maxrmargin = p->defrmargin;
149*95c635efSGarrett D'Amore 	p->tabwidth = term_len(p, 5);
150*95c635efSGarrett D'Amore 
151*95c635efSGarrett D'Amore 	if (NULL == p->symtab)
152*95c635efSGarrett D'Amore 		p->symtab = mchars_alloc();
153*95c635efSGarrett D'Amore 
154*95c635efSGarrett D'Amore 	n = man_node(man);
155*95c635efSGarrett D'Amore 	m = man_meta(man);
156*95c635efSGarrett D'Amore 
157*95c635efSGarrett D'Amore 	term_begin(p, print_man_head, print_man_foot, m);
158*95c635efSGarrett D'Amore 	p->flags |= TERMP_NOSPACE;
159*95c635efSGarrett D'Amore 
160*95c635efSGarrett D'Amore 	memset(&mt, 0, sizeof(struct mtermp));
161*95c635efSGarrett D'Amore 
162*95c635efSGarrett D'Amore 	mt.lmargin[mt.lmargincur] = term_len(p, p->defindent);
163*95c635efSGarrett D'Amore 	mt.offset = term_len(p, p->defindent);
164*95c635efSGarrett D'Amore 
165*95c635efSGarrett D'Amore 	if (n->child)
166*95c635efSGarrett D'Amore 		print_man_nodelist(p, &mt, n->child, m);
167*95c635efSGarrett D'Amore 
168*95c635efSGarrett D'Amore 	term_end(p);
169*95c635efSGarrett D'Amore }
170*95c635efSGarrett D'Amore 
171*95c635efSGarrett D'Amore 
172*95c635efSGarrett D'Amore static size_t
173*95c635efSGarrett D'Amore a2height(const struct termp *p, const char *cp)
174*95c635efSGarrett D'Amore {
175*95c635efSGarrett D'Amore 	struct roffsu	 su;
176*95c635efSGarrett D'Amore 
177*95c635efSGarrett D'Amore 	if ( ! a2roffsu(cp, &su, SCALE_VS))
178*95c635efSGarrett D'Amore 		SCALE_VS_INIT(&su, atoi(cp));
179*95c635efSGarrett D'Amore 
180*95c635efSGarrett D'Amore 	return(term_vspan(p, &su));
181*95c635efSGarrett D'Amore }
182*95c635efSGarrett D'Amore 
183*95c635efSGarrett D'Amore 
184*95c635efSGarrett D'Amore static int
185*95c635efSGarrett D'Amore a2width(const struct termp *p, const char *cp)
186*95c635efSGarrett D'Amore {
187*95c635efSGarrett D'Amore 	struct roffsu	 su;
188*95c635efSGarrett D'Amore 
189*95c635efSGarrett D'Amore 	if ( ! a2roffsu(cp, &su, SCALE_BU))
190*95c635efSGarrett D'Amore 		return(-1);
191*95c635efSGarrett D'Amore 
192*95c635efSGarrett D'Amore 	return((int)term_hspan(p, &su));
193*95c635efSGarrett D'Amore }
194*95c635efSGarrett D'Amore 
195*95c635efSGarrett D'Amore /*
196*95c635efSGarrett D'Amore  * Printing leading vertical space before a block.
197*95c635efSGarrett D'Amore  * This is used for the paragraph macros.
198*95c635efSGarrett D'Amore  * The rules are pretty simple, since there's very little nesting going
199*95c635efSGarrett D'Amore  * on here.  Basically, if we're the first within another block (SS/SH),
200*95c635efSGarrett D'Amore  * then don't emit vertical space.  If we are (RS), then do.  If not the
201*95c635efSGarrett D'Amore  * first, print it.
202*95c635efSGarrett D'Amore  */
203*95c635efSGarrett D'Amore static void
204*95c635efSGarrett D'Amore print_bvspace(struct termp *p, const struct man_node *n)
205*95c635efSGarrett D'Amore {
206*95c635efSGarrett D'Amore 
207*95c635efSGarrett D'Amore 	term_newln(p);
208*95c635efSGarrett D'Amore 
209*95c635efSGarrett D'Amore 	if (n->body && n->body->child)
210*95c635efSGarrett D'Amore 		if (MAN_TBL == n->body->child->type)
211*95c635efSGarrett D'Amore 			return;
212*95c635efSGarrett D'Amore 
213*95c635efSGarrett D'Amore 	if (MAN_ROOT == n->parent->type || MAN_RS != n->parent->tok)
214*95c635efSGarrett D'Amore 		if (NULL == n->prev)
215*95c635efSGarrett D'Amore 			return;
216*95c635efSGarrett D'Amore 
217*95c635efSGarrett D'Amore 	term_vspace(p);
218*95c635efSGarrett D'Amore }
219*95c635efSGarrett D'Amore 
220*95c635efSGarrett D'Amore /* ARGSUSED */
221*95c635efSGarrett D'Amore static int
222*95c635efSGarrett D'Amore pre_ign(DECL_ARGS)
223*95c635efSGarrett D'Amore {
224*95c635efSGarrett D'Amore 
225*95c635efSGarrett D'Amore 	return(0);
226*95c635efSGarrett D'Amore }
227*95c635efSGarrett D'Amore 
228*95c635efSGarrett D'Amore 
229*95c635efSGarrett D'Amore /* ARGSUSED */
230*95c635efSGarrett D'Amore static int
231*95c635efSGarrett D'Amore pre_I(DECL_ARGS)
232*95c635efSGarrett D'Amore {
233*95c635efSGarrett D'Amore 
234*95c635efSGarrett D'Amore 	term_fontrepl(p, TERMFONT_UNDER);
235*95c635efSGarrett D'Amore 	return(1);
236*95c635efSGarrett D'Amore }
237*95c635efSGarrett D'Amore 
238*95c635efSGarrett D'Amore 
239*95c635efSGarrett D'Amore /* ARGSUSED */
240*95c635efSGarrett D'Amore static int
241*95c635efSGarrett D'Amore pre_literal(DECL_ARGS)
242*95c635efSGarrett D'Amore {
243*95c635efSGarrett D'Amore 
244*95c635efSGarrett D'Amore 	term_newln(p);
245*95c635efSGarrett D'Amore 
246*95c635efSGarrett D'Amore 	if (MAN_nf == n->tok)
247*95c635efSGarrett D'Amore 		mt->fl |= MANT_LITERAL;
248*95c635efSGarrett D'Amore 	else
249*95c635efSGarrett D'Amore 		mt->fl &= ~MANT_LITERAL;
250*95c635efSGarrett D'Amore 
251*95c635efSGarrett D'Amore 	/*
252*95c635efSGarrett D'Amore 	 * Unlike .IP and .TP, .HP does not have a HEAD.
253*95c635efSGarrett D'Amore 	 * So in case a second call to term_flushln() is needed,
254*95c635efSGarrett D'Amore 	 * indentation has to be set up explicitly.
255*95c635efSGarrett D'Amore 	 */
256*95c635efSGarrett D'Amore 	if (MAN_HP == n->parent->tok && p->rmargin < p->maxrmargin) {
257*95c635efSGarrett D'Amore 		p->offset = p->rmargin;
258*95c635efSGarrett D'Amore 		p->rmargin = p->maxrmargin;
259*95c635efSGarrett D'Amore 		p->flags &= ~(TERMP_NOBREAK | TERMP_TWOSPACE);
260*95c635efSGarrett D'Amore 		p->flags |= TERMP_NOSPACE;
261*95c635efSGarrett D'Amore 	}
262*95c635efSGarrett D'Amore 
263*95c635efSGarrett D'Amore 	return(0);
264*95c635efSGarrett D'Amore }
265*95c635efSGarrett D'Amore 
266*95c635efSGarrett D'Amore /* ARGSUSED */
267*95c635efSGarrett D'Amore static int
268*95c635efSGarrett D'Amore pre_alternate(DECL_ARGS)
269*95c635efSGarrett D'Amore {
270*95c635efSGarrett D'Amore 	enum termfont		 font[2];
271*95c635efSGarrett D'Amore 	const struct man_node	*nn;
272*95c635efSGarrett D'Amore 	int			 savelit, i;
273*95c635efSGarrett D'Amore 
274*95c635efSGarrett D'Amore 	switch (n->tok) {
275*95c635efSGarrett D'Amore 	case (MAN_RB):
276*95c635efSGarrett D'Amore 		font[0] = TERMFONT_NONE;
277*95c635efSGarrett D'Amore 		font[1] = TERMFONT_BOLD;
278*95c635efSGarrett D'Amore 		break;
279*95c635efSGarrett D'Amore 	case (MAN_RI):
280*95c635efSGarrett D'Amore 		font[0] = TERMFONT_NONE;
281*95c635efSGarrett D'Amore 		font[1] = TERMFONT_UNDER;
282*95c635efSGarrett D'Amore 		break;
283*95c635efSGarrett D'Amore 	case (MAN_BR):
284*95c635efSGarrett D'Amore 		font[0] = TERMFONT_BOLD;
285*95c635efSGarrett D'Amore 		font[1] = TERMFONT_NONE;
286*95c635efSGarrett D'Amore 		break;
287*95c635efSGarrett D'Amore 	case (MAN_BI):
288*95c635efSGarrett D'Amore 		font[0] = TERMFONT_BOLD;
289*95c635efSGarrett D'Amore 		font[1] = TERMFONT_UNDER;
290*95c635efSGarrett D'Amore 		break;
291*95c635efSGarrett D'Amore 	case (MAN_IR):
292*95c635efSGarrett D'Amore 		font[0] = TERMFONT_UNDER;
293*95c635efSGarrett D'Amore 		font[1] = TERMFONT_NONE;
294*95c635efSGarrett D'Amore 		break;
295*95c635efSGarrett D'Amore 	case (MAN_IB):
296*95c635efSGarrett D'Amore 		font[0] = TERMFONT_UNDER;
297*95c635efSGarrett D'Amore 		font[1] = TERMFONT_BOLD;
298*95c635efSGarrett D'Amore 		break;
299*95c635efSGarrett D'Amore 	default:
300*95c635efSGarrett D'Amore 		abort();
301*95c635efSGarrett D'Amore 	}
302*95c635efSGarrett D'Amore 
303*95c635efSGarrett D'Amore 	savelit = MANT_LITERAL & mt->fl;
304*95c635efSGarrett D'Amore 	mt->fl &= ~MANT_LITERAL;
305*95c635efSGarrett D'Amore 
306*95c635efSGarrett D'Amore 	for (i = 0, nn = n->child; nn; nn = nn->next, i = 1 - i) {
307*95c635efSGarrett D'Amore 		term_fontrepl(p, font[i]);
308*95c635efSGarrett D'Amore 		if (savelit && NULL == nn->next)
309*95c635efSGarrett D'Amore 			mt->fl |= MANT_LITERAL;
310*95c635efSGarrett D'Amore 		print_man_node(p, mt, nn, m);
311*95c635efSGarrett D'Amore 		if (nn->next)
312*95c635efSGarrett D'Amore 			p->flags |= TERMP_NOSPACE;
313*95c635efSGarrett D'Amore 	}
314*95c635efSGarrett D'Amore 
315*95c635efSGarrett D'Amore 	return(0);
316*95c635efSGarrett D'Amore }
317*95c635efSGarrett D'Amore 
318*95c635efSGarrett D'Amore /* ARGSUSED */
319*95c635efSGarrett D'Amore static int
320*95c635efSGarrett D'Amore pre_B(DECL_ARGS)
321*95c635efSGarrett D'Amore {
322*95c635efSGarrett D'Amore 
323*95c635efSGarrett D'Amore 	term_fontrepl(p, TERMFONT_BOLD);
324*95c635efSGarrett D'Amore 	return(1);
325*95c635efSGarrett D'Amore }
326*95c635efSGarrett D'Amore 
327*95c635efSGarrett D'Amore /* ARGSUSED */
328*95c635efSGarrett D'Amore static int
329*95c635efSGarrett D'Amore pre_OP(DECL_ARGS)
330*95c635efSGarrett D'Amore {
331*95c635efSGarrett D'Amore 
332*95c635efSGarrett D'Amore 	term_word(p, "[");
333*95c635efSGarrett D'Amore 	p->flags |= TERMP_NOSPACE;
334*95c635efSGarrett D'Amore 
335*95c635efSGarrett D'Amore 	if (NULL != (n = n->child)) {
336*95c635efSGarrett D'Amore 		term_fontrepl(p, TERMFONT_BOLD);
337*95c635efSGarrett D'Amore 		term_word(p, n->string);
338*95c635efSGarrett D'Amore 	}
339*95c635efSGarrett D'Amore 	if (NULL != n && NULL != n->next) {
340*95c635efSGarrett D'Amore 		term_fontrepl(p, TERMFONT_UNDER);
341*95c635efSGarrett D'Amore 		term_word(p, n->next->string);
342*95c635efSGarrett D'Amore 	}
343*95c635efSGarrett D'Amore 
344*95c635efSGarrett D'Amore 	term_fontrepl(p, TERMFONT_NONE);
345*95c635efSGarrett D'Amore 	p->flags |= TERMP_NOSPACE;
346*95c635efSGarrett D'Amore 	term_word(p, "]");
347*95c635efSGarrett D'Amore 	return(0);
348*95c635efSGarrett D'Amore }
349*95c635efSGarrett D'Amore 
350*95c635efSGarrett D'Amore /* ARGSUSED */
351*95c635efSGarrett D'Amore static int
352*95c635efSGarrett D'Amore pre_ft(DECL_ARGS)
353*95c635efSGarrett D'Amore {
354*95c635efSGarrett D'Amore 	const char	*cp;
355*95c635efSGarrett D'Amore 
356*95c635efSGarrett D'Amore 	if (NULL == n->child) {
357*95c635efSGarrett D'Amore 		term_fontlast(p);
358*95c635efSGarrett D'Amore 		return(0);
359*95c635efSGarrett D'Amore 	}
360*95c635efSGarrett D'Amore 
361*95c635efSGarrett D'Amore 	cp = n->child->string;
362*95c635efSGarrett D'Amore 	switch (*cp) {
363*95c635efSGarrett D'Amore 	case ('4'):
364*95c635efSGarrett D'Amore 		/* FALLTHROUGH */
365*95c635efSGarrett D'Amore 	case ('3'):
366*95c635efSGarrett D'Amore 		/* FALLTHROUGH */
367*95c635efSGarrett D'Amore 	case ('B'):
368*95c635efSGarrett D'Amore 		term_fontrepl(p, TERMFONT_BOLD);
369*95c635efSGarrett D'Amore 		break;
370*95c635efSGarrett D'Amore 	case ('2'):
371*95c635efSGarrett D'Amore 		/* FALLTHROUGH */
372*95c635efSGarrett D'Amore 	case ('I'):
373*95c635efSGarrett D'Amore 		term_fontrepl(p, TERMFONT_UNDER);
374*95c635efSGarrett D'Amore 		break;
375*95c635efSGarrett D'Amore 	case ('P'):
376*95c635efSGarrett D'Amore 		term_fontlast(p);
377*95c635efSGarrett D'Amore 		break;
378*95c635efSGarrett D'Amore 	case ('1'):
379*95c635efSGarrett D'Amore 		/* FALLTHROUGH */
380*95c635efSGarrett D'Amore 	case ('C'):
381*95c635efSGarrett D'Amore 		/* FALLTHROUGH */
382*95c635efSGarrett D'Amore 	case ('R'):
383*95c635efSGarrett D'Amore 		term_fontrepl(p, TERMFONT_NONE);
384*95c635efSGarrett D'Amore 		break;
385*95c635efSGarrett D'Amore 	default:
386*95c635efSGarrett D'Amore 		break;
387*95c635efSGarrett D'Amore 	}
388*95c635efSGarrett D'Amore 	return(0);
389*95c635efSGarrett D'Amore }
390*95c635efSGarrett D'Amore 
391*95c635efSGarrett D'Amore /* ARGSUSED */
392*95c635efSGarrett D'Amore static int
393*95c635efSGarrett D'Amore pre_in(DECL_ARGS)
394*95c635efSGarrett D'Amore {
395*95c635efSGarrett D'Amore 	int		 len, less;
396*95c635efSGarrett D'Amore 	size_t		 v;
397*95c635efSGarrett D'Amore 	const char	*cp;
398*95c635efSGarrett D'Amore 
399*95c635efSGarrett D'Amore 	term_newln(p);
400*95c635efSGarrett D'Amore 
401*95c635efSGarrett D'Amore 	if (NULL == n->child) {
402*95c635efSGarrett D'Amore 		p->offset = mt->offset;
403*95c635efSGarrett D'Amore 		return(0);
404*95c635efSGarrett D'Amore 	}
405*95c635efSGarrett D'Amore 
406*95c635efSGarrett D'Amore 	cp = n->child->string;
407*95c635efSGarrett D'Amore 	less = 0;
408*95c635efSGarrett D'Amore 
409*95c635efSGarrett D'Amore 	if ('-' == *cp)
410*95c635efSGarrett D'Amore 		less = -1;
411*95c635efSGarrett D'Amore 	else if ('+' == *cp)
412*95c635efSGarrett D'Amore 		less = 1;
413*95c635efSGarrett D'Amore 	else
414*95c635efSGarrett D'Amore 		cp--;
415*95c635efSGarrett D'Amore 
416*95c635efSGarrett D'Amore 	if ((len = a2width(p, ++cp)) < 0)
417*95c635efSGarrett D'Amore 		return(0);
418*95c635efSGarrett D'Amore 
419*95c635efSGarrett D'Amore 	v = (size_t)len;
420*95c635efSGarrett D'Amore 
421*95c635efSGarrett D'Amore 	if (less < 0)
422*95c635efSGarrett D'Amore 		p->offset -= p->offset > v ? v : p->offset;
423*95c635efSGarrett D'Amore 	else if (less > 0)
424*95c635efSGarrett D'Amore 		p->offset += v;
425*95c635efSGarrett D'Amore 	else
426*95c635efSGarrett D'Amore 		p->offset = v;
427*95c635efSGarrett D'Amore 
428*95c635efSGarrett D'Amore 	/* Don't let this creep beyond the right margin. */
429*95c635efSGarrett D'Amore 
430*95c635efSGarrett D'Amore 	if (p->offset > p->rmargin)
431*95c635efSGarrett D'Amore 		p->offset = p->rmargin;
432*95c635efSGarrett D'Amore 
433*95c635efSGarrett D'Amore 	return(0);
434*95c635efSGarrett D'Amore }
435*95c635efSGarrett D'Amore 
436*95c635efSGarrett D'Amore 
437*95c635efSGarrett D'Amore /* ARGSUSED */
438*95c635efSGarrett D'Amore static int
439*95c635efSGarrett D'Amore pre_sp(DECL_ARGS)
440*95c635efSGarrett D'Amore {
441*95c635efSGarrett D'Amore 	size_t		 i, len;
442*95c635efSGarrett D'Amore 
443*95c635efSGarrett D'Amore 	if ((NULL == n->prev && n->parent)) {
444*95c635efSGarrett D'Amore 		if (MAN_SS == n->parent->tok)
445*95c635efSGarrett D'Amore 			return(0);
446*95c635efSGarrett D'Amore 		if (MAN_SH == n->parent->tok)
447*95c635efSGarrett D'Amore 			return(0);
448*95c635efSGarrett D'Amore 	}
449*95c635efSGarrett D'Amore 
450*95c635efSGarrett D'Amore 	switch (n->tok) {
451*95c635efSGarrett D'Amore 	case (MAN_br):
452*95c635efSGarrett D'Amore 		len = 0;
453*95c635efSGarrett D'Amore 		break;
454*95c635efSGarrett D'Amore 	default:
455*95c635efSGarrett D'Amore 		len = n->child ? a2height(p, n->child->string) : 1;
456*95c635efSGarrett D'Amore 		break;
457*95c635efSGarrett D'Amore 	}
458*95c635efSGarrett D'Amore 
459*95c635efSGarrett D'Amore 	if (0 == len)
460*95c635efSGarrett D'Amore 		term_newln(p);
461*95c635efSGarrett D'Amore 	for (i = 0; i < len; i++)
462*95c635efSGarrett D'Amore 		term_vspace(p);
463*95c635efSGarrett D'Amore 
464*95c635efSGarrett D'Amore 	return(0);
465*95c635efSGarrett D'Amore }
466*95c635efSGarrett D'Amore 
467*95c635efSGarrett D'Amore 
468*95c635efSGarrett D'Amore /* ARGSUSED */
469*95c635efSGarrett D'Amore static int
470*95c635efSGarrett D'Amore pre_HP(DECL_ARGS)
471*95c635efSGarrett D'Amore {
472*95c635efSGarrett D'Amore 	size_t			 len, one;
473*95c635efSGarrett D'Amore 	int			 ival;
474*95c635efSGarrett D'Amore 	const struct man_node	*nn;
475*95c635efSGarrett D'Amore 
476*95c635efSGarrett D'Amore 	switch (n->type) {
477*95c635efSGarrett D'Amore 	case (MAN_BLOCK):
478*95c635efSGarrett D'Amore 		print_bvspace(p, n);
479*95c635efSGarrett D'Amore 		return(1);
480*95c635efSGarrett D'Amore 	case (MAN_BODY):
481*95c635efSGarrett D'Amore 		p->flags |= TERMP_NOBREAK;
482*95c635efSGarrett D'Amore 		p->flags |= TERMP_TWOSPACE;
483*95c635efSGarrett D'Amore 		break;
484*95c635efSGarrett D'Amore 	default:
485*95c635efSGarrett D'Amore 		return(0);
486*95c635efSGarrett D'Amore 	}
487*95c635efSGarrett D'Amore 
488*95c635efSGarrett D'Amore 	len = mt->lmargin[mt->lmargincur];
489*95c635efSGarrett D'Amore 	ival = -1;
490*95c635efSGarrett D'Amore 
491*95c635efSGarrett D'Amore 	/* Calculate offset. */
492*95c635efSGarrett D'Amore 
493*95c635efSGarrett D'Amore 	if (NULL != (nn = n->parent->head->child))
494*95c635efSGarrett D'Amore 		if ((ival = a2width(p, nn->string)) >= 0)
495*95c635efSGarrett D'Amore 			len = (size_t)ival;
496*95c635efSGarrett D'Amore 
497*95c635efSGarrett D'Amore 	one = term_len(p, 1);
498*95c635efSGarrett D'Amore 	if (len < one)
499*95c635efSGarrett D'Amore 		len = one;
500*95c635efSGarrett D'Amore 
501*95c635efSGarrett D'Amore 	p->offset = mt->offset;
502*95c635efSGarrett D'Amore 	p->rmargin = mt->offset + len;
503*95c635efSGarrett D'Amore 
504*95c635efSGarrett D'Amore 	if (ival >= 0)
505*95c635efSGarrett D'Amore 		mt->lmargin[mt->lmargincur] = (size_t)ival;
506*95c635efSGarrett D'Amore 
507*95c635efSGarrett D'Amore 	return(1);
508*95c635efSGarrett D'Amore }
509*95c635efSGarrett D'Amore 
510*95c635efSGarrett D'Amore 
511*95c635efSGarrett D'Amore /* ARGSUSED */
512*95c635efSGarrett D'Amore static void
513*95c635efSGarrett D'Amore post_HP(DECL_ARGS)
514*95c635efSGarrett D'Amore {
515*95c635efSGarrett D'Amore 
516*95c635efSGarrett D'Amore 	switch (n->type) {
517*95c635efSGarrett D'Amore 	case (MAN_BLOCK):
518*95c635efSGarrett D'Amore 		term_flushln(p);
519*95c635efSGarrett D'Amore 		break;
520*95c635efSGarrett D'Amore 	case (MAN_BODY):
521*95c635efSGarrett D'Amore 		term_flushln(p);
522*95c635efSGarrett D'Amore 		p->flags &= ~TERMP_NOBREAK;
523*95c635efSGarrett D'Amore 		p->flags &= ~TERMP_TWOSPACE;
524*95c635efSGarrett D'Amore 		p->offset = mt->offset;
525*95c635efSGarrett D'Amore 		p->rmargin = p->maxrmargin;
526*95c635efSGarrett D'Amore 		break;
527*95c635efSGarrett D'Amore 	default:
528*95c635efSGarrett D'Amore 		break;
529*95c635efSGarrett D'Amore 	}
530*95c635efSGarrett D'Amore }
531*95c635efSGarrett D'Amore 
532*95c635efSGarrett D'Amore 
533*95c635efSGarrett D'Amore /* ARGSUSED */
534*95c635efSGarrett D'Amore static int
535*95c635efSGarrett D'Amore pre_PP(DECL_ARGS)
536*95c635efSGarrett D'Amore {
537*95c635efSGarrett D'Amore 
538*95c635efSGarrett D'Amore 	switch (n->type) {
539*95c635efSGarrett D'Amore 	case (MAN_BLOCK):
540*95c635efSGarrett D'Amore 		mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
541*95c635efSGarrett D'Amore 		print_bvspace(p, n);
542*95c635efSGarrett D'Amore 		break;
543*95c635efSGarrett D'Amore 	default:
544*95c635efSGarrett D'Amore 		p->offset = mt->offset;
545*95c635efSGarrett D'Amore 		break;
546*95c635efSGarrett D'Amore 	}
547*95c635efSGarrett D'Amore 
548*95c635efSGarrett D'Amore 	return(MAN_HEAD != n->type);
549*95c635efSGarrett D'Amore }
550*95c635efSGarrett D'Amore 
551*95c635efSGarrett D'Amore 
552*95c635efSGarrett D'Amore /* ARGSUSED */
553*95c635efSGarrett D'Amore static int
554*95c635efSGarrett D'Amore pre_IP(DECL_ARGS)
555*95c635efSGarrett D'Amore {
556*95c635efSGarrett D'Amore 	const struct man_node	*nn;
557*95c635efSGarrett D'Amore 	size_t			 len;
558*95c635efSGarrett D'Amore 	int			 savelit, ival;
559*95c635efSGarrett D'Amore 
560*95c635efSGarrett D'Amore 	switch (n->type) {
561*95c635efSGarrett D'Amore 	case (MAN_BODY):
562*95c635efSGarrett D'Amore 		p->flags |= TERMP_NOSPACE;
563*95c635efSGarrett D'Amore 		break;
564*95c635efSGarrett D'Amore 	case (MAN_HEAD):
565*95c635efSGarrett D'Amore 		p->flags |= TERMP_NOBREAK;
566*95c635efSGarrett D'Amore 		break;
567*95c635efSGarrett D'Amore 	case (MAN_BLOCK):
568*95c635efSGarrett D'Amore 		print_bvspace(p, n);
569*95c635efSGarrett D'Amore 		/* FALLTHROUGH */
570*95c635efSGarrett D'Amore 	default:
571*95c635efSGarrett D'Amore 		return(1);
572*95c635efSGarrett D'Amore 	}
573*95c635efSGarrett D'Amore 
574*95c635efSGarrett D'Amore 	len = mt->lmargin[mt->lmargincur];
575*95c635efSGarrett D'Amore 	ival = -1;
576*95c635efSGarrett D'Amore 
577*95c635efSGarrett D'Amore 	/* Calculate the offset from the optional second argument. */
578*95c635efSGarrett D'Amore 	if (NULL != (nn = n->parent->head->child))
579*95c635efSGarrett D'Amore 		if (NULL != (nn = nn->next))
580*95c635efSGarrett D'Amore 			if ((ival = a2width(p, nn->string)) >= 0)
581*95c635efSGarrett D'Amore 				len = (size_t)ival;
582*95c635efSGarrett D'Amore 
583*95c635efSGarrett D'Amore 	switch (n->type) {
584*95c635efSGarrett D'Amore 	case (MAN_HEAD):
585*95c635efSGarrett D'Amore 		/* Handle zero-width lengths. */
586*95c635efSGarrett D'Amore 		if (0 == len)
587*95c635efSGarrett D'Amore 			len = term_len(p, 1);
588*95c635efSGarrett D'Amore 
589*95c635efSGarrett D'Amore 		p->offset = mt->offset;
590*95c635efSGarrett D'Amore 		p->rmargin = mt->offset + len;
591*95c635efSGarrett D'Amore 		if (ival < 0)
592*95c635efSGarrett D'Amore 			break;
593*95c635efSGarrett D'Amore 
594*95c635efSGarrett D'Amore 		/* Set the saved left-margin. */
595*95c635efSGarrett D'Amore 		mt->lmargin[mt->lmargincur] = (size_t)ival;
596*95c635efSGarrett D'Amore 
597*95c635efSGarrett D'Amore 		savelit = MANT_LITERAL & mt->fl;
598*95c635efSGarrett D'Amore 		mt->fl &= ~MANT_LITERAL;
599*95c635efSGarrett D'Amore 
600*95c635efSGarrett D'Amore 		if (n->child)
601*95c635efSGarrett D'Amore 			print_man_node(p, mt, n->child, m);
602*95c635efSGarrett D'Amore 
603*95c635efSGarrett D'Amore 		if (savelit)
604*95c635efSGarrett D'Amore 			mt->fl |= MANT_LITERAL;
605*95c635efSGarrett D'Amore 
606*95c635efSGarrett D'Amore 		return(0);
607*95c635efSGarrett D'Amore 	case (MAN_BODY):
608*95c635efSGarrett D'Amore 		p->offset = mt->offset + len;
609*95c635efSGarrett D'Amore 		p->rmargin = p->maxrmargin;
610*95c635efSGarrett D'Amore 		break;
611*95c635efSGarrett D'Amore 	default:
612*95c635efSGarrett D'Amore 		break;
613*95c635efSGarrett D'Amore 	}
614*95c635efSGarrett D'Amore 
615*95c635efSGarrett D'Amore 	return(1);
616*95c635efSGarrett D'Amore }
617*95c635efSGarrett D'Amore 
618*95c635efSGarrett D'Amore 
619*95c635efSGarrett D'Amore /* ARGSUSED */
620*95c635efSGarrett D'Amore static void
621*95c635efSGarrett D'Amore post_IP(DECL_ARGS)
622*95c635efSGarrett D'Amore {
623*95c635efSGarrett D'Amore 
624*95c635efSGarrett D'Amore 	switch (n->type) {
625*95c635efSGarrett D'Amore 	case (MAN_HEAD):
626*95c635efSGarrett D'Amore 		term_flushln(p);
627*95c635efSGarrett D'Amore 		p->flags &= ~TERMP_NOBREAK;
628*95c635efSGarrett D'Amore 		p->rmargin = p->maxrmargin;
629*95c635efSGarrett D'Amore 		break;
630*95c635efSGarrett D'Amore 	case (MAN_BODY):
631*95c635efSGarrett D'Amore 		term_newln(p);
632*95c635efSGarrett D'Amore 		break;
633*95c635efSGarrett D'Amore 	default:
634*95c635efSGarrett D'Amore 		break;
635*95c635efSGarrett D'Amore 	}
636*95c635efSGarrett D'Amore }
637*95c635efSGarrett D'Amore 
638*95c635efSGarrett D'Amore 
639*95c635efSGarrett D'Amore /* ARGSUSED */
640*95c635efSGarrett D'Amore static int
641*95c635efSGarrett D'Amore pre_TP(DECL_ARGS)
642*95c635efSGarrett D'Amore {
643*95c635efSGarrett D'Amore 	const struct man_node	*nn;
644*95c635efSGarrett D'Amore 	size_t			 len;
645*95c635efSGarrett D'Amore 	int			 savelit, ival;
646*95c635efSGarrett D'Amore 
647*95c635efSGarrett D'Amore 	switch (n->type) {
648*95c635efSGarrett D'Amore 	case (MAN_HEAD):
649*95c635efSGarrett D'Amore 		p->flags |= TERMP_NOBREAK;
650*95c635efSGarrett D'Amore 		break;
651*95c635efSGarrett D'Amore 	case (MAN_BODY):
652*95c635efSGarrett D'Amore 		p->flags |= TERMP_NOSPACE;
653*95c635efSGarrett D'Amore 		break;
654*95c635efSGarrett D'Amore 	case (MAN_BLOCK):
655*95c635efSGarrett D'Amore 		print_bvspace(p, n);
656*95c635efSGarrett D'Amore 		/* FALLTHROUGH */
657*95c635efSGarrett D'Amore 	default:
658*95c635efSGarrett D'Amore 		return(1);
659*95c635efSGarrett D'Amore 	}
660*95c635efSGarrett D'Amore 
661*95c635efSGarrett D'Amore 	len = (size_t)mt->lmargin[mt->lmargincur];
662*95c635efSGarrett D'Amore 	ival = -1;
663*95c635efSGarrett D'Amore 
664*95c635efSGarrett D'Amore 	/* Calculate offset. */
665*95c635efSGarrett D'Amore 
666*95c635efSGarrett D'Amore 	if (NULL != (nn = n->parent->head->child))
667*95c635efSGarrett D'Amore 		if (nn->string && nn->parent->line == nn->line)
668*95c635efSGarrett D'Amore 			if ((ival = a2width(p, nn->string)) >= 0)
669*95c635efSGarrett D'Amore 				len = (size_t)ival;
670*95c635efSGarrett D'Amore 
671*95c635efSGarrett D'Amore 	switch (n->type) {
672*95c635efSGarrett D'Amore 	case (MAN_HEAD):
673*95c635efSGarrett D'Amore 		/* Handle zero-length properly. */
674*95c635efSGarrett D'Amore 		if (0 == len)
675*95c635efSGarrett D'Amore 			len = term_len(p, 1);
676*95c635efSGarrett D'Amore 
677*95c635efSGarrett D'Amore 		p->offset = mt->offset;
678*95c635efSGarrett D'Amore 		p->rmargin = mt->offset + len;
679*95c635efSGarrett D'Amore 
680*95c635efSGarrett D'Amore 		savelit = MANT_LITERAL & mt->fl;
681*95c635efSGarrett D'Amore 		mt->fl &= ~MANT_LITERAL;
682*95c635efSGarrett D'Amore 
683*95c635efSGarrett D'Amore 		/* Don't print same-line elements. */
684*95c635efSGarrett D'Amore 		for (nn = n->child; nn; nn = nn->next)
685*95c635efSGarrett D'Amore 			if (nn->line > n->line)
686*95c635efSGarrett D'Amore 				print_man_node(p, mt, nn, m);
687*95c635efSGarrett D'Amore 
688*95c635efSGarrett D'Amore 		if (savelit)
689*95c635efSGarrett D'Amore 			mt->fl |= MANT_LITERAL;
690*95c635efSGarrett D'Amore 		if (ival >= 0)
691*95c635efSGarrett D'Amore 			mt->lmargin[mt->lmargincur] = (size_t)ival;
692*95c635efSGarrett D'Amore 
693*95c635efSGarrett D'Amore 		return(0);
694*95c635efSGarrett D'Amore 	case (MAN_BODY):
695*95c635efSGarrett D'Amore 		p->offset = mt->offset + len;
696*95c635efSGarrett D'Amore 		p->rmargin = p->maxrmargin;
697*95c635efSGarrett D'Amore 		break;
698*95c635efSGarrett D'Amore 	default:
699*95c635efSGarrett D'Amore 		break;
700*95c635efSGarrett D'Amore 	}
701*95c635efSGarrett D'Amore 
702*95c635efSGarrett D'Amore 	return(1);
703*95c635efSGarrett D'Amore }
704*95c635efSGarrett D'Amore 
705*95c635efSGarrett D'Amore 
706*95c635efSGarrett D'Amore /* ARGSUSED */
707*95c635efSGarrett D'Amore static void
708*95c635efSGarrett D'Amore post_TP(DECL_ARGS)
709*95c635efSGarrett D'Amore {
710*95c635efSGarrett D'Amore 
711*95c635efSGarrett D'Amore 	switch (n->type) {
712*95c635efSGarrett D'Amore 	case (MAN_HEAD):
713*95c635efSGarrett D'Amore 		term_flushln(p);
714*95c635efSGarrett D'Amore 		p->flags &= ~TERMP_NOBREAK;
715*95c635efSGarrett D'Amore 		p->flags &= ~TERMP_TWOSPACE;
716*95c635efSGarrett D'Amore 		p->rmargin = p->maxrmargin;
717*95c635efSGarrett D'Amore 		break;
718*95c635efSGarrett D'Amore 	case (MAN_BODY):
719*95c635efSGarrett D'Amore 		term_newln(p);
720*95c635efSGarrett D'Amore 		break;
721*95c635efSGarrett D'Amore 	default:
722*95c635efSGarrett D'Amore 		break;
723*95c635efSGarrett D'Amore 	}
724*95c635efSGarrett D'Amore }
725*95c635efSGarrett D'Amore 
726*95c635efSGarrett D'Amore 
727*95c635efSGarrett D'Amore /* ARGSUSED */
728*95c635efSGarrett D'Amore static int
729*95c635efSGarrett D'Amore pre_SS(DECL_ARGS)
730*95c635efSGarrett D'Amore {
731*95c635efSGarrett D'Amore 
732*95c635efSGarrett D'Amore 	switch (n->type) {
733*95c635efSGarrett D'Amore 	case (MAN_BLOCK):
734*95c635efSGarrett D'Amore 		mt->fl &= ~MANT_LITERAL;
735*95c635efSGarrett D'Amore 		mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
736*95c635efSGarrett D'Amore 		mt->offset = term_len(p, p->defindent);
737*95c635efSGarrett D'Amore 		/* If following a prior empty `SS', no vspace. */
738*95c635efSGarrett D'Amore 		if (n->prev && MAN_SS == n->prev->tok)
739*95c635efSGarrett D'Amore 			if (NULL == n->prev->body->child)
740*95c635efSGarrett D'Amore 				break;
741*95c635efSGarrett D'Amore 		if (NULL == n->prev)
742*95c635efSGarrett D'Amore 			break;
743*95c635efSGarrett D'Amore 		term_vspace(p);
744*95c635efSGarrett D'Amore 		break;
745*95c635efSGarrett D'Amore 	case (MAN_HEAD):
746*95c635efSGarrett D'Amore 		term_fontrepl(p, TERMFONT_BOLD);
747*95c635efSGarrett D'Amore 		p->offset = term_len(p, p->defindent/2);
748*95c635efSGarrett D'Amore 		break;
749*95c635efSGarrett D'Amore 	case (MAN_BODY):
750*95c635efSGarrett D'Amore 		p->offset = mt->offset;
751*95c635efSGarrett D'Amore 		break;
752*95c635efSGarrett D'Amore 	default:
753*95c635efSGarrett D'Amore 		break;
754*95c635efSGarrett D'Amore 	}
755*95c635efSGarrett D'Amore 
756*95c635efSGarrett D'Amore 	return(1);
757*95c635efSGarrett D'Amore }
758*95c635efSGarrett D'Amore 
759*95c635efSGarrett D'Amore 
760*95c635efSGarrett D'Amore /* ARGSUSED */
761*95c635efSGarrett D'Amore static void
762*95c635efSGarrett D'Amore post_SS(DECL_ARGS)
763*95c635efSGarrett D'Amore {
764*95c635efSGarrett D'Amore 
765*95c635efSGarrett D'Amore 	switch (n->type) {
766*95c635efSGarrett D'Amore 	case (MAN_HEAD):
767*95c635efSGarrett D'Amore 		term_newln(p);
768*95c635efSGarrett D'Amore 		break;
769*95c635efSGarrett D'Amore 	case (MAN_BODY):
770*95c635efSGarrett D'Amore 		term_newln(p);
771*95c635efSGarrett D'Amore 		break;
772*95c635efSGarrett D'Amore 	default:
773*95c635efSGarrett D'Amore 		break;
774*95c635efSGarrett D'Amore 	}
775*95c635efSGarrett D'Amore }
776*95c635efSGarrett D'Amore 
777*95c635efSGarrett D'Amore 
778*95c635efSGarrett D'Amore /* ARGSUSED */
779*95c635efSGarrett D'Amore static int
780*95c635efSGarrett D'Amore pre_SH(DECL_ARGS)
781*95c635efSGarrett D'Amore {
782*95c635efSGarrett D'Amore 
783*95c635efSGarrett D'Amore 	switch (n->type) {
784*95c635efSGarrett D'Amore 	case (MAN_BLOCK):
785*95c635efSGarrett D'Amore 		mt->fl &= ~MANT_LITERAL;
786*95c635efSGarrett D'Amore 		mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
787*95c635efSGarrett D'Amore 		mt->offset = term_len(p, p->defindent);
788*95c635efSGarrett D'Amore 		/* If following a prior empty `SH', no vspace. */
789*95c635efSGarrett D'Amore 		if (n->prev && MAN_SH == n->prev->tok)
790*95c635efSGarrett D'Amore 			if (NULL == n->prev->body->child)
791*95c635efSGarrett D'Amore 				break;
792*95c635efSGarrett D'Amore 		/* If the first macro, no vspae. */
793*95c635efSGarrett D'Amore 		if (NULL == n->prev)
794*95c635efSGarrett D'Amore 			break;
795*95c635efSGarrett D'Amore 		term_vspace(p);
796*95c635efSGarrett D'Amore 		break;
797*95c635efSGarrett D'Amore 	case (MAN_HEAD):
798*95c635efSGarrett D'Amore 		term_fontrepl(p, TERMFONT_BOLD);
799*95c635efSGarrett D'Amore 		p->offset = 0;
800*95c635efSGarrett D'Amore 		break;
801*95c635efSGarrett D'Amore 	case (MAN_BODY):
802*95c635efSGarrett D'Amore 		p->offset = mt->offset;
803*95c635efSGarrett D'Amore 		break;
804*95c635efSGarrett D'Amore 	default:
805*95c635efSGarrett D'Amore 		break;
806*95c635efSGarrett D'Amore 	}
807*95c635efSGarrett D'Amore 
808*95c635efSGarrett D'Amore 	return(1);
809*95c635efSGarrett D'Amore }
810*95c635efSGarrett D'Amore 
811*95c635efSGarrett D'Amore 
812*95c635efSGarrett D'Amore /* ARGSUSED */
813*95c635efSGarrett D'Amore static void
814*95c635efSGarrett D'Amore post_SH(DECL_ARGS)
815*95c635efSGarrett D'Amore {
816*95c635efSGarrett D'Amore 
817*95c635efSGarrett D'Amore 	switch (n->type) {
818*95c635efSGarrett D'Amore 	case (MAN_HEAD):
819*95c635efSGarrett D'Amore 		term_newln(p);
820*95c635efSGarrett D'Amore 		break;
821*95c635efSGarrett D'Amore 	case (MAN_BODY):
822*95c635efSGarrett D'Amore 		term_newln(p);
823*95c635efSGarrett D'Amore 		break;
824*95c635efSGarrett D'Amore 	default:
825*95c635efSGarrett D'Amore 		break;
826*95c635efSGarrett D'Amore 	}
827*95c635efSGarrett D'Amore }
828*95c635efSGarrett D'Amore 
829*95c635efSGarrett D'Amore /* ARGSUSED */
830*95c635efSGarrett D'Amore static int
831*95c635efSGarrett D'Amore pre_RS(DECL_ARGS)
832*95c635efSGarrett D'Amore {
833*95c635efSGarrett D'Amore 	int		 ival;
834*95c635efSGarrett D'Amore 	size_t		 sz;
835*95c635efSGarrett D'Amore 
836*95c635efSGarrett D'Amore 	switch (n->type) {
837*95c635efSGarrett D'Amore 	case (MAN_BLOCK):
838*95c635efSGarrett D'Amore 		term_newln(p);
839*95c635efSGarrett D'Amore 		return(1);
840*95c635efSGarrett D'Amore 	case (MAN_HEAD):
841*95c635efSGarrett D'Amore 		return(0);
842*95c635efSGarrett D'Amore 	default:
843*95c635efSGarrett D'Amore 		break;
844*95c635efSGarrett D'Amore 	}
845*95c635efSGarrett D'Amore 
846*95c635efSGarrett D'Amore 	sz = term_len(p, p->defindent);
847*95c635efSGarrett D'Amore 
848*95c635efSGarrett D'Amore 	if (NULL != (n = n->parent->head->child))
849*95c635efSGarrett D'Amore 		if ((ival = a2width(p, n->string)) >= 0)
850*95c635efSGarrett D'Amore 			sz = (size_t)ival;
851*95c635efSGarrett D'Amore 
852*95c635efSGarrett D'Amore 	mt->offset += sz;
853*95c635efSGarrett D'Amore 	p->rmargin = p->maxrmargin;
854*95c635efSGarrett D'Amore 	p->offset = mt->offset < p->rmargin ? mt->offset : p->rmargin;
855*95c635efSGarrett D'Amore 
856*95c635efSGarrett D'Amore 	if (++mt->lmarginsz < MAXMARGINS)
857*95c635efSGarrett D'Amore 		mt->lmargincur = mt->lmarginsz;
858*95c635efSGarrett D'Amore 
859*95c635efSGarrett D'Amore 	mt->lmargin[mt->lmargincur] = mt->lmargin[mt->lmargincur - 1];
860*95c635efSGarrett D'Amore 	return(1);
861*95c635efSGarrett D'Amore }
862*95c635efSGarrett D'Amore 
863*95c635efSGarrett D'Amore /* ARGSUSED */
864*95c635efSGarrett D'Amore static void
865*95c635efSGarrett D'Amore post_RS(DECL_ARGS)
866*95c635efSGarrett D'Amore {
867*95c635efSGarrett D'Amore 	int		 ival;
868*95c635efSGarrett D'Amore 	size_t		 sz;
869*95c635efSGarrett D'Amore 
870*95c635efSGarrett D'Amore 	switch (n->type) {
871*95c635efSGarrett D'Amore 	case (MAN_BLOCK):
872*95c635efSGarrett D'Amore 		return;
873*95c635efSGarrett D'Amore 	case (MAN_HEAD):
874*95c635efSGarrett D'Amore 		return;
875*95c635efSGarrett D'Amore 	default:
876*95c635efSGarrett D'Amore 		term_newln(p);
877*95c635efSGarrett D'Amore 		break;
878*95c635efSGarrett D'Amore 	}
879*95c635efSGarrett D'Amore 
880*95c635efSGarrett D'Amore 	sz = term_len(p, p->defindent);
881*95c635efSGarrett D'Amore 
882*95c635efSGarrett D'Amore 	if (NULL != (n = n->parent->head->child))
883*95c635efSGarrett D'Amore 		if ((ival = a2width(p, n->string)) >= 0)
884*95c635efSGarrett D'Amore 			sz = (size_t)ival;
885*95c635efSGarrett D'Amore 
886*95c635efSGarrett D'Amore 	mt->offset = mt->offset < sz ?  0 : mt->offset - sz;
887*95c635efSGarrett D'Amore 	p->offset = mt->offset;
888*95c635efSGarrett D'Amore 
889*95c635efSGarrett D'Amore 	if (--mt->lmarginsz < MAXMARGINS)
890*95c635efSGarrett D'Amore 		mt->lmargincur = mt->lmarginsz;
891*95c635efSGarrett D'Amore }
892*95c635efSGarrett D'Amore 
893*95c635efSGarrett D'Amore static void
894*95c635efSGarrett D'Amore print_man_node(DECL_ARGS)
895*95c635efSGarrett D'Amore {
896*95c635efSGarrett D'Amore 	size_t		 rm, rmax;
897*95c635efSGarrett D'Amore 	int		 c;
898*95c635efSGarrett D'Amore 
899*95c635efSGarrett D'Amore 	switch (n->type) {
900*95c635efSGarrett D'Amore 	case(MAN_TEXT):
901*95c635efSGarrett D'Amore 		/*
902*95c635efSGarrett D'Amore 		 * If we have a blank line, output a vertical space.
903*95c635efSGarrett D'Amore 		 * If we have a space as the first character, break
904*95c635efSGarrett D'Amore 		 * before printing the line's data.
905*95c635efSGarrett D'Amore 		 */
906*95c635efSGarrett D'Amore 		if ('\0' == *n->string) {
907*95c635efSGarrett D'Amore 			term_vspace(p);
908*95c635efSGarrett D'Amore 			return;
909*95c635efSGarrett D'Amore 		} else if (' ' == *n->string && MAN_LINE & n->flags)
910*95c635efSGarrett D'Amore 			term_newln(p);
911*95c635efSGarrett D'Amore 
912*95c635efSGarrett D'Amore 		term_word(p, n->string);
913*95c635efSGarrett D'Amore 
914*95c635efSGarrett D'Amore 		/*
915*95c635efSGarrett D'Amore 		 * If we're in a literal context, make sure that words
916*95c635efSGarrett D'Amore 		 * togehter on the same line stay together.  This is a
917*95c635efSGarrett D'Amore 		 * POST-printing call, so we check the NEXT word.  Since
918*95c635efSGarrett D'Amore 		 * -man doesn't have nested macros, we don't need to be
919*95c635efSGarrett D'Amore 		 * more specific than this.
920*95c635efSGarrett D'Amore 		 */
921*95c635efSGarrett D'Amore 		if (MANT_LITERAL & mt->fl && ! (TERMP_NOBREAK & p->flags) &&
922*95c635efSGarrett D'Amore 				(NULL == n->next ||
923*95c635efSGarrett D'Amore 				 n->next->line > n->line)) {
924*95c635efSGarrett D'Amore 			rm = p->rmargin;
925*95c635efSGarrett D'Amore 			rmax = p->maxrmargin;
926*95c635efSGarrett D'Amore 			p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
927*95c635efSGarrett D'Amore 			p->flags |= TERMP_NOSPACE;
928*95c635efSGarrett D'Amore 			term_flushln(p);
929*95c635efSGarrett D'Amore 			p->rmargin = rm;
930*95c635efSGarrett D'Amore 			p->maxrmargin = rmax;
931*95c635efSGarrett D'Amore 		}
932*95c635efSGarrett D'Amore 
933*95c635efSGarrett D'Amore 		if (MAN_EOS & n->flags)
934*95c635efSGarrett D'Amore 			p->flags |= TERMP_SENTENCE;
935*95c635efSGarrett D'Amore 		return;
936*95c635efSGarrett D'Amore 	case (MAN_EQN):
937*95c635efSGarrett D'Amore 		term_eqn(p, n->eqn);
938*95c635efSGarrett D'Amore 		return;
939*95c635efSGarrett D'Amore 	case (MAN_TBL):
940*95c635efSGarrett D'Amore 		/*
941*95c635efSGarrett D'Amore 		 * Tables are preceded by a newline.  Then process a
942*95c635efSGarrett D'Amore 		 * table line, which will cause line termination,
943*95c635efSGarrett D'Amore 		 */
944*95c635efSGarrett D'Amore 		if (TBL_SPAN_FIRST & n->span->flags)
945*95c635efSGarrett D'Amore 			term_newln(p);
946*95c635efSGarrett D'Amore 		term_tbl(p, n->span);
947*95c635efSGarrett D'Amore 		return;
948*95c635efSGarrett D'Amore 	default:
949*95c635efSGarrett D'Amore 		break;
950*95c635efSGarrett D'Amore 	}
951*95c635efSGarrett D'Amore 
952*95c635efSGarrett D'Amore 	if ( ! (MAN_NOTEXT & termacts[n->tok].flags))
953*95c635efSGarrett D'Amore 		term_fontrepl(p, TERMFONT_NONE);
954*95c635efSGarrett D'Amore 
955*95c635efSGarrett D'Amore 	c = 1;
956*95c635efSGarrett D'Amore 	if (termacts[n->tok].pre)
957*95c635efSGarrett D'Amore 		c = (*termacts[n->tok].pre)(p, mt, n, m);
958*95c635efSGarrett D'Amore 
959*95c635efSGarrett D'Amore 	if (c && n->child)
960*95c635efSGarrett D'Amore 		print_man_nodelist(p, mt, n->child, m);
961*95c635efSGarrett D'Amore 
962*95c635efSGarrett D'Amore 	if (termacts[n->tok].post)
963*95c635efSGarrett D'Amore 		(*termacts[n->tok].post)(p, mt, n, m);
964*95c635efSGarrett D'Amore 	if ( ! (MAN_NOTEXT & termacts[n->tok].flags))
965*95c635efSGarrett D'Amore 		term_fontrepl(p, TERMFONT_NONE);
966*95c635efSGarrett D'Amore 
967*95c635efSGarrett D'Amore 	if (MAN_EOS & n->flags)
968*95c635efSGarrett D'Amore 		p->flags |= TERMP_SENTENCE;
969*95c635efSGarrett D'Amore }
970*95c635efSGarrett D'Amore 
971*95c635efSGarrett D'Amore 
972*95c635efSGarrett D'Amore static void
973*95c635efSGarrett D'Amore print_man_nodelist(DECL_ARGS)
974*95c635efSGarrett D'Amore {
975*95c635efSGarrett D'Amore 
976*95c635efSGarrett D'Amore 	print_man_node(p, mt, n, m);
977*95c635efSGarrett D'Amore 	if ( ! n->next)
978*95c635efSGarrett D'Amore 		return;
979*95c635efSGarrett D'Amore 	print_man_nodelist(p, mt, n->next, m);
980*95c635efSGarrett D'Amore }
981*95c635efSGarrett D'Amore 
982*95c635efSGarrett D'Amore 
983*95c635efSGarrett D'Amore static void
984*95c635efSGarrett D'Amore print_man_foot(struct termp *p, const void *arg)
985*95c635efSGarrett D'Amore {
986*95c635efSGarrett D'Amore 	char		title[BUFSIZ];
987*95c635efSGarrett D'Amore 	size_t		datelen;
988*95c635efSGarrett D'Amore 	const struct man_meta *meta;
989*95c635efSGarrett D'Amore 
990*95c635efSGarrett D'Amore 	meta = (const struct man_meta *)arg;
991*95c635efSGarrett D'Amore 	assert(meta->title);
992*95c635efSGarrett D'Amore 	assert(meta->msec);
993*95c635efSGarrett D'Amore 	assert(meta->date);
994*95c635efSGarrett D'Amore 
995*95c635efSGarrett D'Amore 	term_fontrepl(p, TERMFONT_NONE);
996*95c635efSGarrett D'Amore 
997*95c635efSGarrett D'Amore 	term_vspace(p);
998*95c635efSGarrett D'Amore 
999*95c635efSGarrett D'Amore 	/*
1000*95c635efSGarrett D'Amore 	 * Temporary, undocumented option to imitate mdoc(7) output.
1001*95c635efSGarrett D'Amore 	 * In the bottom right corner, use the source instead of
1002*95c635efSGarrett D'Amore 	 * the title.
1003*95c635efSGarrett D'Amore 	 */
1004*95c635efSGarrett D'Amore 
1005*95c635efSGarrett D'Amore 	if ( ! p->mdocstyle) {
1006*95c635efSGarrett D'Amore 		term_vspace(p);
1007*95c635efSGarrett D'Amore 		term_vspace(p);
1008*95c635efSGarrett D'Amore 		snprintf(title, BUFSIZ, "%s(%s)", meta->title, meta->msec);
1009*95c635efSGarrett D'Amore 	} else if (meta->source) {
1010*95c635efSGarrett D'Amore 		strlcpy(title, meta->source, BUFSIZ);
1011*95c635efSGarrett D'Amore 	} else {
1012*95c635efSGarrett D'Amore 		title[0] = '\0';
1013*95c635efSGarrett D'Amore 	}
1014*95c635efSGarrett D'Amore 	datelen = term_strlen(p, meta->date);
1015*95c635efSGarrett D'Amore 
1016*95c635efSGarrett D'Amore 	/* Bottom left corner: manual source. */
1017*95c635efSGarrett D'Amore 
1018*95c635efSGarrett D'Amore 	p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
1019*95c635efSGarrett D'Amore 	p->offset = 0;
1020*95c635efSGarrett D'Amore 	p->rmargin = (p->maxrmargin - datelen + term_len(p, 1)) / 2;
1021*95c635efSGarrett D'Amore 
1022*95c635efSGarrett D'Amore 	if (meta->source)
1023*95c635efSGarrett D'Amore 		term_word(p, meta->source);
1024*95c635efSGarrett D'Amore 	term_flushln(p);
1025*95c635efSGarrett D'Amore 
1026*95c635efSGarrett D'Amore 	/* At the bottom in the middle: manual date. */
1027*95c635efSGarrett D'Amore 
1028*95c635efSGarrett D'Amore 	p->flags |= TERMP_NOSPACE;
1029*95c635efSGarrett D'Amore 	p->offset = p->rmargin;
1030*95c635efSGarrett D'Amore 	p->rmargin = p->maxrmargin - term_strlen(p, title);
1031*95c635efSGarrett D'Amore 	if (p->offset + datelen >= p->rmargin)
1032*95c635efSGarrett D'Amore 		p->rmargin = p->offset + datelen;
1033*95c635efSGarrett D'Amore 
1034*95c635efSGarrett D'Amore 	term_word(p, meta->date);
1035*95c635efSGarrett D'Amore 	term_flushln(p);
1036*95c635efSGarrett D'Amore 
1037*95c635efSGarrett D'Amore 	/* Bottom right corner: manual title and section. */
1038*95c635efSGarrett D'Amore 
1039*95c635efSGarrett D'Amore 	p->flags &= ~TERMP_NOBREAK;
1040*95c635efSGarrett D'Amore 	p->flags |= TERMP_NOSPACE;
1041*95c635efSGarrett D'Amore 	p->offset = p->rmargin;
1042*95c635efSGarrett D'Amore 	p->rmargin = p->maxrmargin;
1043*95c635efSGarrett D'Amore 
1044*95c635efSGarrett D'Amore 	term_word(p, title);
1045*95c635efSGarrett D'Amore 	term_flushln(p);
1046*95c635efSGarrett D'Amore }
1047*95c635efSGarrett D'Amore 
1048*95c635efSGarrett D'Amore 
1049*95c635efSGarrett D'Amore static void
1050*95c635efSGarrett D'Amore print_man_head(struct termp *p, const void *arg)
1051*95c635efSGarrett D'Amore {
1052*95c635efSGarrett D'Amore 	char		buf[BUFSIZ], title[BUFSIZ];
1053*95c635efSGarrett D'Amore 	size_t		buflen, titlen;
1054*95c635efSGarrett D'Amore 	const struct man_meta *m;
1055*95c635efSGarrett D'Amore 
1056*95c635efSGarrett D'Amore 	m = (const struct man_meta *)arg;
1057*95c635efSGarrett D'Amore 	assert(m->title);
1058*95c635efSGarrett D'Amore 	assert(m->msec);
1059*95c635efSGarrett D'Amore 
1060*95c635efSGarrett D'Amore 	if (m->vol)
1061*95c635efSGarrett D'Amore 		strlcpy(buf, m->vol, BUFSIZ);
1062*95c635efSGarrett D'Amore 	else
1063*95c635efSGarrett D'Amore 		buf[0] = '\0';
1064*95c635efSGarrett D'Amore 	buflen = term_strlen(p, buf);
1065*95c635efSGarrett D'Amore 
1066*95c635efSGarrett D'Amore 	/* Top left corner: manual title and section. */
1067*95c635efSGarrett D'Amore 
1068*95c635efSGarrett D'Amore 	snprintf(title, BUFSIZ, "%s(%s)", m->title, m->msec);
1069*95c635efSGarrett D'Amore 	titlen = term_strlen(p, title);
1070*95c635efSGarrett D'Amore 
1071*95c635efSGarrett D'Amore 	p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
1072*95c635efSGarrett D'Amore 	p->offset = 0;
1073*95c635efSGarrett D'Amore 	p->rmargin = 2 * (titlen+1) + buflen < p->maxrmargin ?
1074*95c635efSGarrett D'Amore 	    (p->maxrmargin -
1075*95c635efSGarrett D'Amore 	     term_strlen(p, buf) + term_len(p, 1)) / 2 :
1076*95c635efSGarrett D'Amore 	    p->maxrmargin - buflen;
1077*95c635efSGarrett D'Amore 
1078*95c635efSGarrett D'Amore 	term_word(p, title);
1079*95c635efSGarrett D'Amore 	term_flushln(p);
1080*95c635efSGarrett D'Amore 
1081*95c635efSGarrett D'Amore 	/* At the top in the middle: manual volume. */
1082*95c635efSGarrett D'Amore 
1083*95c635efSGarrett D'Amore 	p->flags |= TERMP_NOSPACE;
1084*95c635efSGarrett D'Amore 	p->offset = p->rmargin;
1085*95c635efSGarrett D'Amore 	p->rmargin = p->offset + buflen + titlen < p->maxrmargin ?
1086*95c635efSGarrett D'Amore 	    p->maxrmargin - titlen : p->maxrmargin;
1087*95c635efSGarrett D'Amore 
1088*95c635efSGarrett D'Amore 	term_word(p, buf);
1089*95c635efSGarrett D'Amore 	term_flushln(p);
1090*95c635efSGarrett D'Amore 
1091*95c635efSGarrett D'Amore 	/* Top right corner: title and section, again. */
1092*95c635efSGarrett D'Amore 
1093*95c635efSGarrett D'Amore 	p->flags &= ~TERMP_NOBREAK;
1094*95c635efSGarrett D'Amore 	if (p->rmargin + titlen <= p->maxrmargin) {
1095*95c635efSGarrett D'Amore 		p->flags |= TERMP_NOSPACE;
1096*95c635efSGarrett D'Amore 		p->offset = p->rmargin;
1097*95c635efSGarrett D'Amore 		p->rmargin = p->maxrmargin;
1098*95c635efSGarrett D'Amore 		term_word(p, title);
1099*95c635efSGarrett D'Amore 		term_flushln(p);
1100*95c635efSGarrett D'Amore 	}
1101*95c635efSGarrett D'Amore 
1102*95c635efSGarrett D'Amore 	p->flags &= ~TERMP_NOSPACE;
1103*95c635efSGarrett D'Amore 	p->offset = 0;
1104*95c635efSGarrett D'Amore 	p->rmargin = p->maxrmargin;
1105*95c635efSGarrett D'Amore 
1106*95c635efSGarrett D'Amore 	/*
1107*95c635efSGarrett D'Amore 	 * Groff prints three blank lines before the content.
1108*95c635efSGarrett D'Amore 	 * Do the same, except in the temporary, undocumented
1109*95c635efSGarrett D'Amore 	 * mode imitating mdoc(7) output.
1110*95c635efSGarrett D'Amore 	 */
1111*95c635efSGarrett D'Amore 
1112*95c635efSGarrett D'Amore 	term_vspace(p);
1113*95c635efSGarrett D'Amore 	if ( ! p->mdocstyle) {
1114*95c635efSGarrett D'Amore 		term_vspace(p);
1115*95c635efSGarrett D'Amore 		term_vspace(p);
1116*95c635efSGarrett D'Amore 	}
1117*95c635efSGarrett D'Amore }
1118