summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2019-01-04 03:39:01 +0000
committerIngo Schwarze <schwarze@openbsd.org>2019-01-04 03:39:01 +0000
commit25e3b2f6dc35e12604593e094f906ffebcbdcc13 (patch)
treeb9e84d994dc5e504e96893480c15a6a08cb7251a
parent59deceb691dd9cb155557e9c5dbddb88455747a2 (diff)
downloadmandoc-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--TODO7
-rw-r--r--mdoc_term.c106
2 files changed, 43 insertions, 70 deletions
diff --git a/TODO b/TODO
index 8f05cb9a..d191bea0 100644
--- a/TODO
+++ b/TODO
@@ -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