-/* $OpenBSD: mdoc_term.c,v 1.258 2017/06/01 19:05:15 schwarze Exp $ */
+/* $OpenBSD: mdoc_term.c,v 1.259 2017/06/04 18:48:09 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
size_t save_defindent;
p = (struct termp *)arg;
- p->overstep = 0;
p->rmargin = p->maxrmargin = p->defrmargin;
term_tab_set(p, NULL);
term_tab_set(p, "T");
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;
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)
p->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;
case LIST_column:
if (n->type == ROFFT_HEAD)
return 0;
+ p->minbl = 0;
break;
default:
break;
* 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;
}
if (pretty) {
term_flushln(p);
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG);
+ p->flags |= TERMP_NOPAD;
p->offset = p->rmargin;
p->rmargin = rmargin;
}
term_flushln(p);
p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND |
TERMP_HANG);
+ p->flags |= TERMP_NOPAD;
p->offset = p->rmargin;
p->rmargin = rmargin;
}
-/* $OpenBSD: term.c,v 1.122 2017/06/02 19:21:03 schwarze Exp $ */
+/* $OpenBSD: term.c,v 1.123 2017/06/04 18:48:09 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
* to be broken, start the next line at the right margin instead
* of at the offset. Used together with TERMP_NOBREAK for the tags
* in various kinds of tagged lists.
- * - TERMP_DANGLE: Do not break the output line at the right margin,
+ * - TERMP_HANG: Do not break the output line at the right margin,
* append the next chunk after it even if this one is too long.
* To be used together with TERMP_NOBREAK.
- * - TERMP_HANG: Like TERMP_DANGLE, and also suppress padding before
- * the next chunk if this column is not full.
+ * - TERMP_NOPAD: Start writing at the current position,
+ * do not pad with blank characters up to the offset.
*/
void
term_flushln(struct termp *p)
size_t jhy; /* last hyph before overflow w/r/t j */
size_t maxvis; /* output position of visible boundary */
- /*
- * First, establish the maximum columns of "visible" content.
- * This is usually the difference between the right-margin and
- * an indentation, but can be, for tagged lists or columns, a
- * small set of values.
- *
- * The following unsigned-signed subtractions look strange,
- * but they are actually correct. If the int p->overstep
- * is negative, it gets sign extended. Subtracting that
- * very large size_t effectively adds a small number to dv.
- */
- dv = p->rmargin > p->offset ? p->rmargin - p->offset : 0;
- maxvis = (int)dv > p->overstep ? dv - (size_t)p->overstep : 0;
-
- if (p->flags & TERMP_NOBREAK) {
- dv = p->maxrmargin > p->offset ?
- p->maxrmargin - p->offset : 0;
- bp = (int)dv > p->overstep ?
- dv - (size_t)p->overstep : 0;
- } else
- bp = maxvis;
-
- /*
- * Calculate the required amount of padding.
- */
- vbl = p->offset + p->overstep > p->viscol ?
- p->offset + p->overstep - p->viscol : 0;
-
+ vbl = (p->flags & TERMP_NOPAD) || p->offset < p->viscol ? 0 :
+ p->offset - p->viscol;
+ if (p->minbl && vbl < p->minbl)
+ vbl = p->minbl;
+ maxvis = p->rmargin > p->viscol + vbl ?
+ p->rmargin - p->viscol - vbl : 0;
+ bp = !(p->flags & TERMP_NOBREAK) ? maxvis :
+ p->maxrmargin > p->viscol + vbl ?
+ p->maxrmargin - p->viscol - vbl : 0;
vis = vend = 0;
i = 0;
/* Re-establish indentation. */
- if (p->flags & TERMP_BRIND) {
+ if (p->flags & TERMP_BRIND)
vbl += p->rmargin;
- vend += p->rmargin - p->offset;
- } else
+ else
vbl += p->offset;
-
- /*
- * Remove the p->overstep width.
- * Again, if p->overstep is negative,
- * sign extension does the right thing.
- */
-
- bp += (size_t)p->overstep;
- p->overstep = 0;
+ maxvis = p->rmargin > vbl ? p->rmargin - vbl : 0;
+ bp = !(p->flags & TERMP_NOBREAK) ? maxvis :
+ p->maxrmargin > vbl ? p->maxrmargin - vbl : 0;
}
/* Write out the [remaining] word. */
vis = 0;
p->col = 0;
- p->overstep = 0;
- p->flags &= ~(TERMP_BACKAFTER | TERMP_BACKBEFORE);
+ p->flags &= ~(TERMP_BACKAFTER | TERMP_BACKBEFORE | TERMP_NOPAD);
if ( ! (TERMP_NOBREAK & p->flags)) {
p->viscol = 0;
+ p->minbl = 0;
(*p->endline)(p);
return;
}
if (TERMP_HANG & p->flags) {
- p->overstep += (int)(p->offset + vis - p->rmargin +
- p->trailspace * (*p->width)(p, ' '));
-
- /*
- * If we have overstepped the margin, temporarily move
- * it to the right and flag the rest of the line to be
- * shorter.
- * If there is a request to keep the columns together,
- * allow negative overstep when the column is not full.
- */
- if (p->trailspace && p->overstep < 0)
- p->overstep = 0;
- return;
-
- } else if (TERMP_DANGLE & p->flags)
+ p->minbl = p->trailspace;
return;
+ }
/* Trailing whitespace is significant in some columns. */
if (vis && vbl && (TERMP_BRTRSP & p->flags))
if (maxvis < vis + p->trailspace * (*p->width)(p, ' ')) {
(*p->endline)(p);
p->viscol = 0;
- }
+ p->minbl = 0;
+ } else
+ p->minbl = p->trailspace;
}
/*
-/* $OpenBSD: term.h,v 1.65 2017/05/08 15:33:43 schwarze Exp $ */
+/* $OpenBSD: term.h,v 1.66 2017/06/04 18:48:09 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
size_t col; /* Bytes in buf. */
size_t viscol; /* Chars on current line. */
size_t trailspace; /* See termp_flushln(). */
- int overstep; /* See termp_flushln(). */
+ size_t minbl; /* Minimum blanks before next field. */
int ti; /* Temporary indent for one line. */
int skipvsp; /* Vertical space to skip. */
int flags;
#define TERMP_NOBREAK (1 << 8) /* See term_flushln(). */
#define TERMP_BRTRSP (1 << 9) /* See term_flushln(). */
#define TERMP_BRIND (1 << 10) /* See term_flushln(). */
-#define TERMP_DANGLE (1 << 11) /* See term_flushln(). */
-#define TERMP_HANG (1 << 12) /* See term_flushln(). */
+#define TERMP_HANG (1 << 11) /* See term_flushln(). */
+#define TERMP_NOPAD (1 << 12) /* See term_flushln(). */
#define TERMP_NOSPLIT (1 << 13) /* Do not break line before .An. */
#define TERMP_SPLIT (1 << 14) /* Break line before .An. */
#define TERMP_NONEWLINE (1 << 15) /* No line break in nofill mode. */