diff options
Diffstat (limited to 'usr/src/cmd/mandoc/mdoc_term.c')
| -rw-r--r-- | usr/src/cmd/mandoc/mdoc_term.c | 375 | 
1 files changed, 173 insertions, 202 deletions
| diff --git a/usr/src/cmd/mandoc/mdoc_term.c b/usr/src/cmd/mandoc/mdoc_term.c index e9ea455a48..4e420c5c21 100644 --- a/usr/src/cmd/mandoc/mdoc_term.c +++ b/usr/src/cmd/mandoc/mdoc_term.c @@ -1,4 +1,4 @@ -/*	$Id: mdoc_term.c,v 1.346 2017/02/17 19:15:41 schwarze Exp $ */ +/*	$Id: mdoc_term.c,v 1.364 2017/06/14 17:51:15 schwarze Exp $ */  /*   * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org> @@ -106,7 +106,6 @@ static	int	  termp_ft_pre(DECL_ARGS);  static	int	  termp_in_pre(DECL_ARGS);  static	int	  termp_it_pre(DECL_ARGS);  static	int	  termp_li_pre(DECL_ARGS); -static	int	  termp_ll_pre(DECL_ARGS);  static	int	  termp_lk_pre(DECL_ARGS);  static	int	  termp_nd_pre(DECL_ARGS);  static	int	  termp_nm_pre(DECL_ARGS); @@ -116,7 +115,7 @@ static	int	  termp_rs_pre(DECL_ARGS);  static	int	  termp_sh_pre(DECL_ARGS);  static	int	  termp_skip_pre(DECL_ARGS);  static	int	  termp_sm_pre(DECL_ARGS); -static	int	  termp_sp_pre(DECL_ARGS); +static	int	  termp_pp_pre(DECL_ARGS);  static	int	  termp_ss_pre(DECL_ARGS);  static	int	  termp_sy_pre(DECL_ARGS);  static	int	  termp_tag_pre(DECL_ARGS); @@ -125,14 +124,13 @@ static	int	  termp_vt_pre(DECL_ARGS);  static	int	  termp_xr_pre(DECL_ARGS);  static	int	  termp_xx_pre(DECL_ARGS); -static	const struct termact termacts[MDOC_MAX] = { -	{ termp_ap_pre, NULL }, /* Ap */ +static	const struct termact __termacts[MDOC_MAX - MDOC_Dd] = {  	{ NULL, NULL }, /* Dd */  	{ NULL, NULL }, /* Dt */  	{ NULL, NULL }, /* Os */  	{ termp_sh_pre, termp_sh_post }, /* Sh */  	{ termp_ss_pre, termp_ss_post }, /* Ss */ -	{ termp_sp_pre, NULL }, /* Pp */ +	{ termp_pp_pre, NULL }, /* Pp */  	{ termp_d1_pre, termp_bl_post }, /* D1 */  	{ termp_d1_pre, termp_bl_post }, /* Dl */  	{ termp_bd_pre, termp_bd_post }, /* Bd */ @@ -142,6 +140,7 @@ static	const struct termact termacts[MDOC_MAX] = {  	{ termp_it_pre, termp_it_post }, /* It */  	{ termp_under_pre, NULL }, /* Ad */  	{ termp_an_pre, NULL }, /* An */ +	{ termp_ap_pre, NULL }, /* Ap */  	{ termp_under_pre, NULL }, /* Ar */  	{ termp_cd_pre, NULL }, /* Cd */  	{ termp_bold_pre, NULL }, /* Cm */ @@ -233,7 +232,7 @@ static	const struct termact termacts[MDOC_MAX] = {  	{ termp_under_pre, NULL }, /* Fr */  	{ NULL, NULL }, /* Ud */  	{ NULL, termp_lb_post }, /* Lb */ -	{ termp_sp_pre, NULL }, /* Lp */ +	{ termp_pp_pre, NULL }, /* Lp */  	{ termp_lk_pre, NULL }, /* Lk */  	{ termp_under_pre, NULL }, /* Mt */  	{ termp_quote_pre, termp_quote_post }, /* Brq */ @@ -244,15 +243,14 @@ static	const struct termact termacts[MDOC_MAX] = {  	{ termp_quote_pre, termp_quote_post }, /* En */  	{ termp_xx_pre, termp_xx_post }, /* Dx */  	{ NULL, termp____post }, /* %Q */ -	{ termp_sp_pre, NULL }, /* br */ -	{ termp_sp_pre, NULL }, /* sp */  	{ NULL, termp____post }, /* %U */  	{ NULL, NULL }, /* Ta */ -	{ termp_ll_pre, NULL }, /* ll */  }; +static	const struct termact *const termacts = __termacts - MDOC_Dd;  static	int	 fn_prio; +  void  terminal_mdoc(void *arg, const struct roff_man *mdoc)  { @@ -261,9 +259,10 @@ terminal_mdoc(void *arg, const struct roff_man *mdoc)  	size_t			 save_defindent;  	p = (struct termp *)arg; -	p->overstep = 0; -	p->rmargin = p->maxrmargin = p->defrmargin; -	p->tabwidth = term_len(p, 5); +	p->tcol->rmargin = p->maxrmargin = p->defrmargin; +	term_tab_set(p, NULL); +	term_tab_set(p, "T"); +	term_tab_set(p, ".5i");  	n = mdoc->first->child;  	if (p->synopsisonly) { @@ -317,8 +316,8 @@ print_mdoc_node(DECL_ARGS)  		return;  	chld = 1; -	offset = p->offset; -	rmargin = p->rmargin; +	offset = p->tcol->offset; +	rmargin = p->tcol->rmargin;  	n->flags &= ~NODE_ENDED;  	n->prev_font = p->fonti; @@ -342,7 +341,8 @@ print_mdoc_node(DECL_ARGS)  	switch (n->type) {  	case ROFFT_TEXT: -		if (' ' == *n->string && NODE_LINE & n->flags) +		if (*n->string == ' ' && n->flags & NODE_LINE && +		    (p->flags & TERMP_NONEWLINE) == 0)  			term_newln(p);  		if (NODE_DELIMC & n->flags)  			p->flags |= TERMP_NOSPACE; @@ -363,7 +363,12 @@ print_mdoc_node(DECL_ARGS)  		term_tbl(p, n->span);  		break;  	default: -		if (termacts[n->tok].pre && +		if (n->tok < ROFF_MAX) { +			roff_term_pre(p, n); +			return; +		} +		assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX); +		if (termacts[n->tok].pre != NULL &&  		    (n->end == ENDBODY_NOT || n->child != NULL))  			chld = (*termacts[n->tok].pre)  				(p, &npair, meta, n); @@ -384,7 +389,7 @@ print_mdoc_node(DECL_ARGS)  	case ROFFT_EQN:  		break;  	default: -		if ( ! termacts[n->tok].post || NODE_ENDED & n->flags) +		if (termacts[n->tok].post == NULL || n->flags & NODE_ENDED)  			break;  		(void)(*termacts[n->tok].post)(p, &npair, meta, n); @@ -401,10 +406,9 @@ print_mdoc_node(DECL_ARGS)  	if (NODE_EOS & n->flags)  		p->flags |= TERMP_SENTENCE; -	if (MDOC_ll != n->tok) { -		p->offset = offset; -		p->rmargin = rmargin; -	} +	if (n->type != ROFFT_TEXT) +		p->tcol->offset = offset; +	p->tcol->rmargin = rmargin;  }  static void @@ -424,9 +428,9 @@ print_mdoc_foot(struct termp *p, const struct roff_meta *meta)  	term_vspace(p); -	p->offset = 0; +	p->tcol->offset = 0;  	sz = term_strlen(p, meta->date); -	p->rmargin = p->maxrmargin > sz ? +	p->tcol->rmargin = p->maxrmargin > sz ?  	    (p->maxrmargin + term_len(p, 1) - sz) / 2 : 0;  	p->trailspace = 1;  	p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; @@ -434,16 +438,16 @@ print_mdoc_foot(struct termp *p, const struct roff_meta *meta)  	term_word(p, meta->os);  	term_flushln(p); -	p->offset = p->rmargin; +	p->tcol->offset = p->tcol->rmargin;  	sz = term_strlen(p, meta->os); -	p->rmargin = p->maxrmargin > sz ? p->maxrmargin - sz : 0; +	p->tcol->rmargin = p->maxrmargin > sz ? p->maxrmargin - sz : 0;  	p->flags |= TERMP_NOSPACE;  	term_word(p, meta->date);  	term_flushln(p); -	p->offset = p->rmargin; -	p->rmargin = p->maxrmargin; +	p->tcol->offset = p->tcol->rmargin; +	p->tcol->rmargin = p->maxrmargin;  	p->trailspace = 0;  	p->flags &= ~TERMP_NOBREAK;  	p->flags |= TERMP_NOSPACE; @@ -451,8 +455,8 @@ print_mdoc_foot(struct termp *p, const struct roff_meta *meta)  	term_word(p, meta->os);  	term_flushln(p); -	p->offset = 0; -	p->rmargin = p->maxrmargin; +	p->tcol->offset = 0; +	p->tcol->rmargin = p->maxrmargin;  	p->flags = 0;  } @@ -492,8 +496,8 @@ print_mdoc_head(struct termp *p, const struct roff_meta *meta)  	p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;  	p->trailspace = 1; -	p->offset = 0; -	p->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ? +	p->tcol->offset = 0; +	p->tcol->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ?  	    (p->maxrmargin - vollen + term_len(p, 1)) / 2 :  	    vollen < p->maxrmargin ?  p->maxrmargin - vollen : 0; @@ -501,26 +505,26 @@ print_mdoc_head(struct termp *p, const struct roff_meta *meta)  	term_flushln(p);  	p->flags |= TERMP_NOSPACE; -	p->offset = p->rmargin; -	p->rmargin = p->offset + vollen + titlen < p->maxrmargin ? -	    p->maxrmargin - titlen : p->maxrmargin; +	p->tcol->offset = p->tcol->rmargin; +	p->tcol->rmargin = p->tcol->offset + vollen + titlen < +	    p->maxrmargin ? p->maxrmargin - titlen : p->maxrmargin;  	term_word(p, volume);  	term_flushln(p);  	p->flags &= ~TERMP_NOBREAK;  	p->trailspace = 0; -	if (p->rmargin + titlen <= p->maxrmargin) { +	if (p->tcol->rmargin + titlen <= p->maxrmargin) {  		p->flags |= TERMP_NOSPACE; -		p->offset = p->rmargin; -		p->rmargin = p->maxrmargin; +		p->tcol->offset = p->tcol->rmargin; +		p->tcol->rmargin = p->maxrmargin;  		term_word(p, title);  		term_flushln(p);  	}  	p->flags &= ~TERMP_NOSPACE; -	p->offset = 0; -	p->rmargin = p->maxrmargin; +	p->tcol->offset = 0; +	p->tcol->rmargin = p->maxrmargin;  	free(title);  	free(volume);  } @@ -529,12 +533,14 @@ static int  a2width(const struct termp *p, const char *v)  {  	struct roffsu	 su; +	const char	*end; -	if (a2roffsu(v, &su, SCALE_MAX) < 2) { +	end = a2roffsu(v, &su, SCALE_MAX); +	if (end == NULL || *end != '\0') {  		SCALE_HS_INIT(&su, term_strlen(p, v));  		su.scale /= term_strlen(p, "0");  	} -	return term_hspan(p, &su) / 24; +	return term_hen(p, &su);  }  /* @@ -596,14 +602,6 @@ print_bvspace(struct termp *p,  static int -termp_ll_pre(DECL_ARGS) -{ - -	term_setwidth(p, n->child != NULL ? n->child->string : NULL); -	return 0; -} - -static int  termp_it_pre(DECL_ARGS)  {  	struct roffsu		su; @@ -653,8 +651,8 @@ termp_it_pre(DECL_ARGS)  	if (bl->norm->Bl.offs != NULL) {  		offset = a2width(p, bl->norm->Bl.offs); -		if (offset < 0 && (size_t)(-offset) > p->offset) -			offset = -p->offset; +		if (offset < 0 && (size_t)(-offset) > p->tcol->offset) +			offset = -p->tcol->offset;  		else if (offset > SHRT_MAX)  			offset = 0;  	} @@ -688,7 +686,7 @@ termp_it_pre(DECL_ARGS)  			SCALE_HS_INIT(&su,  			    term_strlen(p, bl->norm->Bl.cols[i]));  			su.scale /= term_strlen(p, "0"); -			offset += term_hspan(p, &su) / 24 + dcol; +			offset += term_hen(p, &su) + dcol;  		}  		/* @@ -706,7 +704,7 @@ termp_it_pre(DECL_ARGS)  		 */  		SCALE_HS_INIT(&su, term_strlen(p, bl->norm->Bl.cols[i]));  		su.scale /= term_strlen(p, "0"); -		width = term_hspan(p, &su) / 24 + dcol; +		width = term_hen(p, &su) + dcol;  		break;  	default:  		if (NULL == bl->norm->Bl.width) @@ -718,8 +716,8 @@ termp_it_pre(DECL_ARGS)  		 * handling for column for how this changes.  		 */  		width = a2width(p, bl->norm->Bl.width) + term_len(p, 2); -		if (width < 0 && (size_t)(-width) > p->offset) -			width = -p->offset; +		if (width < 0 && (size_t)(-width) > p->tcol->offset) +			width = -p->tcol->offset;  		else if (width > SHRT_MAX)  			width = 0;  		break; @@ -768,33 +766,15 @@ termp_it_pre(DECL_ARGS)  	case LIST_bullet:  	case LIST_dash:  	case LIST_hyphen: -		/* -		 * Weird special case. -		 * Some very narrow lists actually hang. -		 */ -		if (width <= (int)term_len(p, 2)) -			p->flags |= TERMP_HANG; -		if (n->type != ROFFT_HEAD) -			break; -		p->flags |= TERMP_NOBREAK; -		p->trailspace = 1; +		if (n->type == ROFFT_HEAD) { +			p->flags |= TERMP_NOBREAK | TERMP_HANG; +			p->trailspace = 1; +		} else if (width <= (int)term_len(p, 2)) +			p->flags |= TERMP_NOPAD;  		break;  	case LIST_hang:  		if (n->type != ROFFT_HEAD)  			break; - -		/* -		 * This is ugly.  If `-hang' is specified and the body -		 * is a `Bl' or `Bd', then we want basically to nullify -		 * the "overstep" effect in term_flushln() and treat -		 * this as a `-ohang' list instead. -		 */ -		if (NULL != n->next && -		    NULL != n->next->child && -		    (MDOC_Bl == n->next->child->tok || -		     MDOC_Bd == n->next->child->tok)) -			break; -  		p->flags |= TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG;  		p->trailspace = 1;  		break; @@ -806,7 +786,7 @@ termp_it_pre(DECL_ARGS)  		p->trailspace = 2;  		if (NULL == n->next || NULL == n->next->child) -			p->flags |= TERMP_DANGLE; +			p->flags |= TERMP_HANG;  		break;  	case LIST_column:  		if (n->type == ROFFT_HEAD) @@ -837,43 +817,31 @@ termp_it_pre(DECL_ARGS)  	 * necessarily lengthened.  Everybody gets the offset.  	 */ -	p->offset += offset; +	p->tcol->offset += offset;  	switch (type) { -	case LIST_hang: -		/* -		 * Same stipulation as above, regarding `-hang'.  We -		 * don't want to recalculate rmargin and offsets when -		 * using `Bd' or `Bl' within `-hang' overstep lists. -		 */ -		if (n->type == ROFFT_HEAD && -		    NULL != n->next && -		    NULL != n->next->child && -		    (MDOC_Bl == n->next->child->tok || -		     MDOC_Bd == n->next->child->tok)) -			break; -		/* FALLTHROUGH */  	case LIST_bullet:  	case LIST_dash:  	case LIST_enum:  	case LIST_hyphen: +	case LIST_hang:  	case LIST_tag:  		if (n->type == ROFFT_HEAD) -			p->rmargin = p->offset + width; +			p->tcol->rmargin = p->tcol->offset + width;  		else -			p->offset += width; +			p->tcol->offset += width;  		break;  	case LIST_column:  		assert(width); -		p->rmargin = p->offset + width; +		p->tcol->rmargin = p->tcol->offset + width;  		/*  		 * XXX - this behaviour is not documented: the  		 * right-most column is filled to the right margin.  		 */  		if (n->type == ROFFT_HEAD)  			break; -		if (NULL == n->next && p->rmargin < p->maxrmargin) -			p->rmargin = p->maxrmargin; +		if (n->next == NULL && p->tcol->rmargin < p->maxrmargin) +			p->tcol->rmargin = p->maxrmargin;  		break;  	default:  		break; @@ -923,6 +891,7 @@ termp_it_pre(DECL_ARGS)  	case LIST_column:  		if (n->type == ROFFT_HEAD)  			return 0; +		p->minbl = 0;  		break;  	default:  		break; @@ -963,8 +932,7 @@ termp_it_post(DECL_ARGS)  	 * has munged them in the meanwhile.  	 */ -	p->flags &= ~(TERMP_NOBREAK | TERMP_BRTRSP | TERMP_BRIND | -			TERMP_DANGLE | TERMP_HANG); +	p->flags &= ~(TERMP_NOBREAK | TERMP_BRTRSP | TERMP_BRIND | TERMP_HANG);  	p->trailspace = 0;  } @@ -979,7 +947,7 @@ termp_nm_pre(DECL_ARGS)  	}  	if (n->type == ROFFT_BODY) { -		if (NULL == n->child) +		if (n->child == NULL)  			return 0;  		p->flags |= TERMP_NOSPACE;  		cp = NULL; @@ -988,9 +956,10 @@ termp_nm_pre(DECL_ARGS)  		if (cp == NULL)  			cp = meta->name;  		if (cp == NULL) -			p->offset += term_len(p, 6); +			p->tcol->offset += term_len(p, 6);  		else -			p->offset += term_len(p, 1) + term_strlen(p, cp); +			p->tcol->offset += term_len(p, 1) + +			    term_strlen(p, cp);  		return 1;  	} @@ -1001,18 +970,18 @@ termp_nm_pre(DECL_ARGS)  		synopsis_pre(p, n->parent);  	if (n->type == ROFFT_HEAD && -	    NULL != n->next && NULL != n->next->child) { +	    n->next != NULL && n->next->child != NULL) {  		p->flags |= TERMP_NOSPACE | TERMP_NOBREAK | TERMP_BRIND;  		p->trailspace = 1; -		p->rmargin = p->offset + term_len(p, 1); -		if (NULL == n->child) { -			p->rmargin += term_strlen(p, meta->name); -		} else if (n->child->type == ROFFT_TEXT) { -			p->rmargin += term_strlen(p, n->child->string); -			if (n->child->next) +		p->tcol->rmargin = p->tcol->offset + term_len(p, 1); +		if (n->child == NULL) +			p->tcol->rmargin += term_strlen(p, meta->name); +		else if (n->child->type == ROFFT_TEXT) { +			p->tcol->rmargin += term_strlen(p, n->child->string); +			if (n->child->next != NULL)  				p->flags |= TERMP_HANG;  		} else { -			p->rmargin += term_len(p, 5); +			p->tcol->rmargin += term_len(p, 5);  			p->flags |= TERMP_HANG;  		}  	} @@ -1135,8 +1104,14 @@ static void  termp_bl_post(DECL_ARGS)  { -	if (n->type == ROFFT_BLOCK) -		term_newln(p); +	if (n->type != ROFFT_BLOCK) +		return; +	term_newln(p); +	if (n->tok != MDOC_Bl || n->norm->Bl.type != LIST_column) +		return; +	term_tab_set(p, NULL); +	term_tab_set(p, "T"); +	term_tab_set(p, ".5i");  }  static int @@ -1278,7 +1253,10 @@ termp_sh_pre(DECL_ARGS)  		term_fontpush(p, TERMFONT_BOLD);  		break;  	case ROFFT_BODY: -		p->offset = term_len(p, p->defindent); +		p->tcol->offset = term_len(p, p->defindent); +		term_tab_set(p, NULL); +		term_tab_set(p, "T"); +		term_tab_set(p, ".5i");  		switch (n->sec) {  		case SEC_DESCRIPTION:  			fn_prio = 0; @@ -1306,7 +1284,7 @@ termp_sh_post(DECL_ARGS)  		break;  	case ROFFT_BODY:  		term_newln(p); -		p->offset = 0; +		p->tcol->offset = 0;  		break;  	default:  		break; @@ -1328,7 +1306,10 @@ termp_d1_pre(DECL_ARGS)  	if (n->type != ROFFT_BLOCK)  		return 1;  	term_newln(p); -	p->offset += term_len(p, p->defindent + 1); +	p->tcol->offset += term_len(p, p->defindent + 1); +	term_tab_set(p, NULL); +	term_tab_set(p, "T"); +	term_tab_set(p, ".5i");  	return 1;  } @@ -1356,8 +1337,8 @@ termp_fn_pre(DECL_ARGS)  		return 0;  	if (pretty) { -		rmargin = p->rmargin; -		p->rmargin = p->offset + term_len(p, 4); +		rmargin = p->tcol->rmargin; +		p->tcol->rmargin = p->tcol->offset + term_len(p, 4);  		p->flags |= TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG;  	} @@ -1372,8 +1353,9 @@ termp_fn_pre(DECL_ARGS)  	if (pretty) {  		term_flushln(p);  		p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG); -		p->offset = p->rmargin; -		p->rmargin = rmargin; +		p->flags |= TERMP_NOPAD; +		p->tcol->offset = p->tcol->rmargin; +		p->tcol->rmargin = rmargin;  	}  	p->flags |= TERMP_NOSPACE; @@ -1434,7 +1416,7 @@ termp_fa_pre(DECL_ARGS)  static int  termp_bd_pre(DECL_ARGS)  { -	size_t			 tabwidth, lm, len, rm, rmax; +	size_t			 lm, len;  	struct roff_node	*nn;  	int			 offset; @@ -1450,15 +1432,15 @@ termp_bd_pre(DECL_ARGS)  	    ! strcmp(n->norm->Bd.offs, "left"))  		/* nothing */;  	else if ( ! strcmp(n->norm->Bd.offs, "indent")) -		p->offset += term_len(p, p->defindent + 1); +		p->tcol->offset += term_len(p, p->defindent + 1);  	else if ( ! strcmp(n->norm->Bd.offs, "indent-two")) -		p->offset += term_len(p, (p->defindent + 1) * 2); +		p->tcol->offset += term_len(p, (p->defindent + 1) * 2);  	else {  		offset = a2width(p, n->norm->Bd.offs); -		if (offset < 0 && (size_t)(-offset) > p->offset) -			p->offset = 0; +		if (offset < 0 && (size_t)(-offset) > p->tcol->offset) +			p->tcol->offset = 0;  		else if (offset < SHRT_MAX) -			p->offset += offset; +			p->tcol->offset += offset;  	}  	/* @@ -1469,29 +1451,29 @@ termp_bd_pre(DECL_ARGS)  	 * lines are allowed.  	 */ -	if (DISP_literal != n->norm->Bd.type && -	    DISP_unfilled != n->norm->Bd.type && -	    DISP_centered != n->norm->Bd.type) +	if (n->norm->Bd.type != DISP_literal && +	    n->norm->Bd.type != DISP_unfilled && +	    n->norm->Bd.type != DISP_centered)  		return 1; -	tabwidth = p->tabwidth; -	if (DISP_literal == n->norm->Bd.type) -		p->tabwidth = term_len(p, 8); - -	lm = p->offset; -	rm = p->rmargin; -	rmax = p->maxrmargin; -	p->rmargin = p->maxrmargin = TERM_MAXMARGIN; +	if (n->norm->Bd.type == DISP_literal) { +		term_tab_set(p, NULL); +		term_tab_set(p, "T"); +		term_tab_set(p, "8n"); +	} -	for (nn = n->child; nn; nn = nn->next) { -		if (DISP_centered == n->norm->Bd.type) { +	lm = p->tcol->offset; +	p->flags |= TERMP_BRNEVER; +	for (nn = n->child; nn != NULL; nn = nn->next) { +		if (n->norm->Bd.type == DISP_centered) {  			if (nn->type == ROFFT_TEXT) {  				len = term_strlen(p, nn->string); -				p->offset = len >= rm ? 0 : -				    lm + len >= rm ? rm - len : -				    (lm + rm - len) / 2; +				p->tcol->offset = len >= p->tcol->rmargin ? +				    0 : lm + len >= p->tcol->rmargin ? +				    p->tcol->rmargin - len : +				    (lm + p->tcol->rmargin - len) / 2;  			} else -				p->offset = lm; +				p->tcol->offset = lm;  		}  		print_mdoc_node(p, pair, meta, nn);  		/* @@ -1500,10 +1482,10 @@ termp_bd_pre(DECL_ARGS)  		 * notion of selective eoln whitespace is pretty dumb  		 * anyway, so don't sweat it.  		 */ +		if (nn->tok < ROFF_MAX) +			continue;  		switch (nn->tok) {  		case MDOC_Sm: -		case MDOC_br: -		case MDOC_sp:  		case MDOC_Bl:  		case MDOC_D1:  		case MDOC_Dl: @@ -1519,33 +1501,21 @@ termp_bd_pre(DECL_ARGS)  		term_flushln(p);  		p->flags |= TERMP_NOSPACE;  	} - -	p->tabwidth = tabwidth; -	p->rmargin = rm; -	p->maxrmargin = rmax; +	p->flags &= ~TERMP_BRNEVER;  	return 0;  }  static void  termp_bd_post(DECL_ARGS)  { -	size_t		 rm, rmax; -  	if (n->type != ROFFT_BODY)  		return; - -	rm = p->rmargin; -	rmax = p->maxrmargin; -  	if (DISP_literal == n->norm->Bd.type ||  	    DISP_unfilled == n->norm->Bd.type) -		p->rmargin = p->maxrmargin = TERM_MAXMARGIN; - +		p->flags |= TERMP_BRNEVER;  	p->flags |= TERMP_NOSPACE;  	term_newln(p); - -	p->rmargin = rm; -	p->maxrmargin = rmax; +	p->flags &= ~TERMP_BRNEVER;  }  static int @@ -1587,10 +1557,13 @@ termp_ss_pre(DECL_ARGS)  		break;  	case ROFFT_HEAD:  		term_fontpush(p, TERMFONT_BOLD); -		p->offset = term_len(p, (p->defindent+1)/2); +		p->tcol->offset = term_len(p, (p->defindent+1)/2);  		break;  	case ROFFT_BODY: -		p->offset = term_len(p, p->defindent); +		p->tcol->offset = term_len(p, p->defindent); +		term_tab_set(p, NULL); +		term_tab_set(p, "T"); +		term_tab_set(p, ".5i");  		break;  	default:  		break; @@ -1650,37 +1623,10 @@ termp_in_post(DECL_ARGS)  }  static int -termp_sp_pre(DECL_ARGS) +termp_pp_pre(DECL_ARGS)  { -	struct roffsu	 su; -	int		 i, len; - -	switch (n->tok) { -	case MDOC_sp: -		if (n->child) { -			if ( ! a2roffsu(n->child->string, &su, SCALE_VS)) -				su.scale = 1.0; -			len = term_vspan(p, &su); -		} else -			len = 1; -		break; -	case MDOC_br: -		len = 0; -		break; -	default: -		len = 1; -		fn_prio = 0; -		break; -	} - -	if (0 == len) -		term_newln(p); -	else if (len < 0) -		p->skipvsp -= len; -	else -		for (i = 0; i < len; i++) -			term_vspace(p); - +	fn_prio = 0; +	term_vspace(p);  	return 0;  } @@ -1861,8 +1807,8 @@ termp_fo_pre(DECL_ARGS)  		return 1;  	} else if (n->type == ROFFT_BODY) {  		if (pretty) { -			rmargin = p->rmargin; -			p->rmargin = p->offset + term_len(p, 4); +			rmargin = p->tcol->rmargin; +			p->tcol->rmargin = p->tcol->offset + term_len(p, 4);  			p->flags |= TERMP_NOBREAK | TERMP_BRIND |  					TERMP_HANG;  		} @@ -1873,8 +1819,9 @@ termp_fo_pre(DECL_ARGS)  			term_flushln(p);  			p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND |  					TERMP_HANG); -			p->offset = p->rmargin; -			p->rmargin = rmargin; +			p->flags |= TERMP_NOPAD; +			p->tcol->offset = p->tcol->rmargin; +			p->tcol->rmargin = rmargin;  		}  		return 1;  	} @@ -1992,26 +1939,50 @@ termp_li_pre(DECL_ARGS)  static int  termp_lk_pre(DECL_ARGS)  { -	const struct roff_node *link, *descr; +	const struct roff_node *link, *descr, *punct; +	int display; -	if (NULL == (link = n->child)) +	if ((link = n->child) == NULL)  		return 0; -	if (NULL != (descr = link->next)) { +	/* Find beginning of trailing punctuation. */ +	punct = n->last; +	while (punct != link && punct->flags & NODE_DELIMC) +		punct = punct->prev; +	punct = punct->next; + +	/* Link text. */ +	if ((descr = link->next) != NULL && descr != punct) {  		term_fontpush(p, TERMFONT_UNDER); -		while (NULL != descr) { +		while (descr != punct) { +			if (descr->flags & (NODE_DELIMC | NODE_DELIMO)) +				p->flags |= TERMP_NOSPACE;  			term_word(p, descr->string);  			descr = descr->next;  		} +		term_fontpop(p);  		p->flags |= TERMP_NOSPACE;  		term_word(p, ":"); -		term_fontpop(p);  	} +	/* Link target. */ +	display = term_strlen(p, link->string) >= 26; +	if (display) { +		term_newln(p); +		p->tcol->offset += term_len(p, p->defindent + 1); +	}  	term_fontpush(p, TERMFONT_BOLD);  	term_word(p, link->string);  	term_fontpop(p); +	/* Trailing punctuation. */ +	while (punct != NULL) { +		p->flags |= TERMP_NOSPACE; +		term_word(p, punct->string); +		punct = punct->next; +	} +	if (display) +		term_newln(p);  	return 0;  } | 
