summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--man.c33
-rw-r--r--man_term.c5
-rw-r--r--mdoc.c28
-rw-r--r--regress/roff/esc/c.in9
-rw-r--r--regress/roff/esc/c.out_ascii4
-rw-r--r--regress/roff/esc/c_man.in9
-rw-r--r--regress/roff/esc/c_man.out_ascii3
7 files changed, 77 insertions, 14 deletions
diff --git a/man.c b/man.c
index 971b15bf..9ca3e0ea 100644
--- a/man.c
+++ b/man.c
@@ -76,6 +76,8 @@ static int
man_ptext(struct roff_man *man, int line, char *buf, int offs)
{
int i;
+ const char *cp, *sp;
+ char *ep;
/* Literal free-form text whitespace is preserved. */
@@ -89,19 +91,36 @@ man_ptext(struct roff_man *man, int line, char *buf, int offs)
/* Skip leading whitespace. */ ;
/*
- * Blank lines are ignored in next line scope and right
- * after headings but add a single vertical space elsewhere.
+ * Blank lines are ignored in next line scope
+ * and right after headings and cancel preceding \c,
+ * but add a single vertical space elsewhere.
*/
if (buf[i] == '\0') {
- if (man->flags & (MAN_ELINE | MAN_BLINE))
+ if (man->flags & (MAN_ELINE | MAN_BLINE)) {
mandoc_msg(MANDOCERR_BLK_BLANK, man->parse,
line, 0, NULL);
- else if (man->last->tok != MAN_SH &&
- man->last->tok != MAN_SS) {
- roff_elem_alloc(man, line, offs, ROFF_sp);
- man->next = ROFF_NEXT_SIBLING;
+ return 1;
}
+ if (man->last->tok == MAN_SH || man->last->tok == MAN_SS)
+ return 1;
+ switch (man->last->type) {
+ case ROFFT_TEXT:
+ sp = man->last->string;
+ cp = ep = strchr(sp, '\0') - 2;
+ if (cp < sp || cp[0] != '\\' || cp[1] != 'c')
+ break;
+ while (cp > sp && cp[-1] == '\\')
+ cp--;
+ if ((ep - cp) % 2)
+ break;
+ *ep = '\0';
+ return 1;
+ default:
+ break;
+ }
+ roff_elem_alloc(man, line, offs, ROFF_sp);
+ man->next = ROFF_NEXT_SIBLING;
return 1;
}
diff --git a/man_term.c b/man_term.c
index 5f527721..f317aadf 100644
--- a/man_term.c
+++ b/man_term.c
@@ -872,7 +872,10 @@ print_man_node(DECL_ARGS)
* before printing the line's data.
*/
if (*n->string == '\0') {
- term_vspace(p);
+ if (p->flags & TERMP_NONEWLINE)
+ term_newln(p);
+ else
+ term_vspace(p);
return;
} else if (*n->string == ' ' && n->flags & NODE_LINE &&
(p->flags & TERMP_NONEWLINE) == 0)
diff --git a/mdoc.c b/mdoc.c
index 4794b0d9..c98cfb15 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -179,6 +179,7 @@ static int
mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
{
struct roff_node *n;
+ const char *cp, *sp;
char *c, *ws, *end;
n = mdoc->last;
@@ -244,15 +245,30 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs)
mandoc_msg(MANDOCERR_SPACE_EOL, mdoc->parse,
line, (int)(ws-buf), NULL);
+ /*
+ * Blank lines are allowed in no-fill mode
+ * and cancel preceding \c,
+ * but add a single vertical space elsewhere.
+ */
+
if (buf[offs] == '\0' && ! (mdoc->flags & MDOC_LITERAL)) {
+ switch (mdoc->last->type) {
+ case ROFFT_TEXT:
+ sp = mdoc->last->string;
+ cp = end = strchr(sp, '\0') - 2;
+ if (cp < sp || cp[0] != '\\' || cp[1] != 'c')
+ break;
+ while (cp > sp && cp[-1] == '\\')
+ cp--;
+ if ((end - cp) % 2)
+ break;
+ *end = '\0';
+ return 1;
+ default:
+ break;
+ }
mandoc_msg(MANDOCERR_FI_BLANK, mdoc->parse,
line, (int)(c - buf), NULL);
-
- /*
- * Insert a `sp' in the case of a blank line. Technically,
- * blank lines aren't allowed, but enough manuals assume this
- * behaviour that we want to work around it.
- */
roff_elem_alloc(mdoc, line, offs, ROFF_sp);
mdoc->last->flags |= NODE_VALID | NODE_ENDED;
mdoc->next = ROFF_NEXT_SIBLING;
diff --git a/regress/roff/esc/c.in b/regress/roff/esc/c.in
index c3b7a912..b7b47bc1 100644
--- a/regress/roff/esc/c.in
+++ b/regress/roff/esc/c.in
@@ -15,3 +15,12 @@ word
one\c
word
.Ed
+Blank line after \ec:
+one\c
+
+word
+.Bd -literal
+one\c
+
+word
+.Ed
diff --git a/regress/roff/esc/c.out_ascii b/regress/roff/esc/c.out_ascii
index a0f6a996..9f8570c4 100644
--- a/regress/roff/esc/c.out_ascii
+++ b/regress/roff/esc/c.out_ascii
@@ -7,5 +7,9 @@ DDEESSCCRRIIPPTTIIOONN
No space between "one" and "word": oneword
oneword
+ Blank line after \c: one word
+
+ one
+ word
OpenBSD December 2, 2014 OpenBSD
diff --git a/regress/roff/esc/c_man.in b/regress/roff/esc/c_man.in
index c18fad10..09e1ed3b 100644
--- a/regress/roff/esc/c_man.in
+++ b/regress/roff/esc/c_man.in
@@ -9,4 +9,13 @@ word
one\c
word
.fi
+Blank line after \ec:
+one\c
+
+word
+.nf
+one\c
+
+word
+.fi
final text
diff --git a/regress/roff/esc/c_man.out_ascii b/regress/roff/esc/c_man.out_ascii
index d00b1b48..9062c335 100644
--- a/regress/roff/esc/c_man.out_ascii
+++ b/regress/roff/esc/c_man.out_ascii
@@ -8,6 +8,9 @@ NNAAMMEE
DDEESSCCRRIIPPTTIIOONN
No space between "one" and "word": oneword
oneword
+ Blank line after \c: one word
+ one
+ word
final text