correct handling of blank lines after \c
authorschwarze <schwarze@openbsd.org>
Sat, 17 Jun 2017 13:05:47 +0000 (13:05 +0000)
committerschwarze <schwarze@openbsd.org>
Sat, 17 Jun 2017 13:05:47 +0000 (13:05 +0000)
regress/usr.bin/mandoc/roff/esc/c.in
regress/usr.bin/mandoc/roff/esc/c.out_ascii
regress/usr.bin/mandoc/roff/esc/c_man.in
regress/usr.bin/mandoc/roff/esc/c_man.out_ascii
usr.bin/mandoc/man.c
usr.bin/mandoc/man_term.c
usr.bin/mandoc/mdoc.c

index c3b7a91..b7b47bc 100644 (file)
@@ -15,3 +15,12 @@ word
 one\c
 word
 .Ed
+Blank line after \ec:
+one\c
+
+word
+.Bd -literal
+one\c
+
+word
+.Ed
index a0f6a99..9f8570c 100644 (file)
@@ -7,5 +7,9 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
      No space between "one" and "word": oneword
 
      oneword
+     Blank line after \c: one word
+
+     one
+     word
 
 OpenBSD                        December 2, 2014                        OpenBSD
index c18fad1..09e1ed3 100644 (file)
@@ -7,6 +7,15 @@ one\c
 word
 .nf
 one\c
+word
+.fi
+Blank line after \ec:
+one\c
+
+word
+.nf
+one\c
+
 word
 .fi
 final text
index d00b1b4..9062c33 100644 (file)
@@ -8,6 +8,9 @@ N\bNA\bAM\bME\bE
 D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
        No space between "one" and "word": oneword
        oneword
+       Blank line after \c: one word
+       one
+       word
        final text
 
 
index ba7cdd8..c6ef632 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: man.c,v 1.122 2017/06/03 15:54:09 schwarze Exp $ */
+/*     $OpenBSD: man.c,v 1.123 2017/06/17 13:05:47 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -74,6 +74,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. */
 
@@ -87,19 +89,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;
        }
 
index c284e3f..7b34366 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: man_term.c,v 1.159 2017/06/17 01:26:48 schwarze Exp $ */
+/*     $OpenBSD: man_term.c,v 1.160 2017/06/17 13:05:47 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -870,7 +870,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)
index bc0ec42..869f4a9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mdoc.c,v 1.155 2017/06/07 20:58:36 schwarze Exp $ */
+/*     $OpenBSD: mdoc.c,v 1.156 2017/06/17 13:05:47 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -177,6 +177,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;
@@ -242,15 +243,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;