]> git.cameronkatri.com Git - mandoc.git/blobdiff - term.c
Added default print of `~' with empty `Pa' (not documented with OpenBSD, but still...
[mandoc.git] / term.c
diff --git a/term.c b/term.c
index 908c58546e5f4a01c14856705adcad3bf3ae36e3..f7b926976a8e6211f833d33d893dd52e4fe89f68 100644 (file)
--- a/term.c
+++ b/term.c
@@ -1,4 +1,4 @@
-/*     $Id: term.c,v 1.89 2009/07/16 13:17:51 kristaps Exp $ */
+/*     $Id: term.c,v 1.91 2009/07/21 13:34:13 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -184,6 +184,9 @@ term_isopendelim(const char *p)
  *    columns.  In short: don't print a newline and instead pad to the
  *    right margin.  Used in conjunction with TERMP_NOLPAD.
  *
+ *  - TERMP_TWOSPACE: when padding, make sure there are at least two
+ *    space characters of padding.  Otherwise, rather break the line.
+ *
  *  - TERMP_DANGLE: don't newline when TERMP_NOBREAK is specified and
  *    the line is overrun, and don't pad-right if it's underrun.
  *
@@ -204,14 +207,17 @@ term_isopendelim(const char *p)
  *  possible).
  *
  *  FIXME: newline breaks occur (in groff) also occur when a single
- *  space follows a NOBREAK!
+ *  space follows a NOBREAK (try `Bl -tag')
+ *
+ *  FIXME: there's a newline error where a `Bl -diag' will have a
+ *  trailing newline if the line is exactly 73 chars long.
  */
 void
 term_flushln(struct termp *p)
 {
        int              i, j;
        size_t           vbl, vsz, vis, maxvis, mmax, bp;
-       static int       sv = -1;
+       static int       overstep = 0;
 
        /*
         * First, establish the maximum columns of "visible" content.
@@ -221,15 +227,11 @@ term_flushln(struct termp *p)
         */
 
        assert(p->offset < p->rmargin);
-       maxvis = p->rmargin - p->offset;
-       mmax = p->maxrmargin - p->offset;
+       maxvis = p->rmargin - p->offset - overstep;
+       mmax = p->maxrmargin - p->offset - overstep;
        bp = TERMP_NOBREAK & p->flags ? mmax : maxvis;
        vis = 0;
-
-       if (sv >= 0) {
-               vis = (size_t)sv;
-               sv = -1;
-       }
+       overstep = 0;
 
        /*
         * If in the standard case (left-justified), then begin with our
@@ -299,38 +301,42 @@ term_flushln(struct termp *p)
                }
                vis += vsz;
        }
+       p->col = 0;
 
-       /*
-        * If we've overstepped our maximum visible no-break space, then
-        * cause a newline and offset at the right margin.
-        */
-
-       if ((TERMP_NOBREAK & p->flags) && vis >= maxvis) {
-               if ( ! (TERMP_DANGLE & p->flags) &&
-                               ! (TERMP_HANG & p->flags)) {
-                       putchar('\n');
-                       for (i = 0; i < (int)p->rmargin; i++)
-                               putchar(' ');
-               }
-               if (TERMP_HANG & p->flags)
-                       sv = (int)(vis - maxvis);
-               p->col = 0;
+       if ( ! (TERMP_NOBREAK & p->flags)) {
+               putchar('\n');
                return;
        }
 
-       /*
-        * If we're not to right-marginalise it (newline), then instead
-        * pad to the right margin and stay off.
-        */
+       if (TERMP_HANG & p->flags) {
 
-       if (p->flags & TERMP_NOBREAK) {
-               if ( ! (TERMP_DANGLE & p->flags))
-                       for ( ; vis < maxvis; vis++)
-                               putchar(' ');
-       } else
-               putchar('\n');
+               /* We need one blank after the tag. */
+               overstep = vis - maxvis + 1;
 
-       p->col = 0;
+               /*
+                * Behave exactly the same way as groff:
+                * If we have overstepped the margin, temporarily move it
+                * to the right and flag the rest of the line to be shorter.
+                * If we landed right at the margin, be happy.
+                * If we are one step before the margin, temporarily move it
+                * one step LEFT and flag the rest of the line to be longer.
+                */
+               if (overstep >= -1)
+                       maxvis += overstep;
+               else
+                       overstep = 0;
+
+       } else if (TERMP_DANGLE & p->flags)
+               return;
+
+       if (maxvis > vis + ((TERMP_TWOSPACE & p->flags) ? 1 : 0))  /* pad */
+               for ( ; vis < maxvis; vis++)
+                       putchar(' ');
+       else {  /* break */
+               putchar('\n');
+               for (i = 0; i < (int)p->rmargin; i++)
+                       putchar(' ');
+       }
 }