diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2019-01-04 03:39:01 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2019-01-04 03:39:01 +0000 |
commit | 25e3b2f6dc35e12604593e094f906ffebcbdcc13 (patch) | |
tree | b9e84d994dc5e504e96893480c15a6a08cb7251a | |
parent | 59deceb691dd9cb155557e9c5dbddb88455747a2 (diff) | |
download | mandoc-25e3b2f6dc35e12604593e094f906ffebcbdcc13.tar.gz |
Two functional improvements to filling in terminal output.
1. Fully support no-fill mode in mdoc(7), even when invoked with
low-level roff(7) .nf requests. As a side effect, this substantially
simplifies the implementation of .Bd -unfilled and .Bd -literal.
2. Let .Bd -centered fill its text, using the new TERMP_CENTER flag.
That finally fixes the long-standing bug that it used to operate in
no-fill mode, which was known to be wrong for at least five years.
This also simplifies the implementation of .Bd -centered considerably.
-rw-r--r-- | TODO | 7 | ||||
-rw-r--r-- | mdoc_term.c | 106 |
2 files changed, 43 insertions, 70 deletions
@@ -90,13 +90,6 @@ are mere guesses, and some may be wrong. from jmc@ Wed, 14 Jul 2010 18:10:32 +0100 loc * exist *** algo *** size ** imp ** -- .Bd -centered implies -filled, not -unfilled, which is not - easy to implement; it requires code similar to .ce, which - we don't have either. - Besides, groff has bug causing text right *before* .Bd -centered - to be centered as well. - loc *** exist *** algo ** size ** imp ** (parser reorg would help) - - .Bd -filled should not be the same as .Bd -ragged, but align both the left and right margin. In groff, it is implemented in terms of .ad b, which we don't have either. Found in cksum(1). diff --git a/mdoc_term.c b/mdoc_term.c index e520ac6f..6ef49375 100644 --- a/mdoc_term.c +++ b/mdoc_term.c @@ -1,7 +1,7 @@ /* $Id$ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010, 2012-2018 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010, 2012-2019 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de> * * Permission to use, copy, modify, and distribute this software for any @@ -312,6 +312,19 @@ print_mdoc_node(DECL_ARGS) size_t offset, rmargin; int chld; + /* + * In no-fill mode, break the output line at the beginning + * of new input lines except after \c, and nowhere else. + */ + + if (n->flags & NODE_NOFILL) { + if (n->flags & NODE_LINE && + (p->flags & TERMP_NONEWLINE) == 0) + term_newln(p); + p->flags |= TERMP_BRNEVER; + } else + p->flags &= ~TERMP_BRNEVER; + if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT) return; @@ -341,9 +354,22 @@ print_mdoc_node(DECL_ARGS) switch (n->type) { case ROFFT_TEXT: - if (*n->string == ' ' && n->flags & NODE_LINE && - (p->flags & TERMP_NONEWLINE) == 0) - term_newln(p); + if (n->flags & NODE_LINE) { + switch (*n->string) { + case '\0': + if (p->flags & TERMP_NONEWLINE) + term_newln(p); + else + term_vspace(p); + return; + case ' ': + if ((p->flags & TERMP_NONEWLINE) == 0) + term_newln(p); + break; + default: + break; + } + } if (NODE_DELIMC & n->flags) p->flags |= TERMP_NOSPACE; term_word(p, n->string); @@ -1418,8 +1444,6 @@ termp_fa_pre(DECL_ARGS) static int termp_bd_pre(DECL_ARGS) { - size_t lm, len; - struct roff_node *nn; int offset; if (n->type == ROFFT_BLOCK) { @@ -1445,65 +1469,19 @@ termp_bd_pre(DECL_ARGS) p->tcol->offset += offset; } - /* - * If -ragged or -filled are specified, the block does nothing - * but change the indentation. If -unfilled or -literal are - * specified, text is printed exactly as entered in the display: - * for macro lines, a newline is appended to the line. Blank - * lines are allowed. - */ - - if (n->norm->Bd.type != DISP_literal && - n->norm->Bd.type != DISP_unfilled && - n->norm->Bd.type != DISP_centered) - return 1; - - if (n->norm->Bd.type == DISP_literal) { + switch (n->norm->Bd.type) { + case DISP_literal: term_tab_set(p, NULL); term_tab_set(p, "T"); term_tab_set(p, "8n"); + break; + case DISP_centered: + p->flags |= TERMP_CENTER; + break; + default: + break; } - - 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->tcol->offset = len >= p->tcol->rmargin ? - 0 : lm + len >= p->tcol->rmargin ? - p->tcol->rmargin - len : - (lm + p->tcol->rmargin - len) / 2; - } else - p->tcol->offset = lm; - } - print_mdoc_node(p, pair, meta, nn); - /* - * If the printed node flushes its own line, then we - * needn't do it here as well. This is hacky, but the - * 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_Bl: - case MDOC_D1: - case MDOC_Dl: - case MDOC_Pp: - continue; - default: - break; - } - if (p->flags & TERMP_NONEWLINE || - (nn->next && ! (nn->next->flags & NODE_LINE))) - continue; - term_flushln(p); - p->flags |= TERMP_NOSPACE; - } - p->flags &= ~TERMP_BRNEVER; - return 0; + return 1; } static void @@ -1511,12 +1489,14 @@ termp_bd_post(DECL_ARGS) { if (n->type != ROFFT_BODY) return; - if (DISP_literal == n->norm->Bd.type || - DISP_unfilled == n->norm->Bd.type) + if (n->norm->Bd.type == DISP_unfilled || + n->norm->Bd.type == DISP_literal) p->flags |= TERMP_BRNEVER; p->flags |= TERMP_NOSPACE; term_newln(p); p->flags &= ~TERMP_BRNEVER; + if (n->norm->Bd.type == DISP_centered) + p->flags &= ~TERMP_CENTER; } static int |