]> git.cameronkatri.com Git - mandoc.git/blobdiff - term.c
In -Tutf8 mode, make sure that hyphens get counted against the output line
[mandoc.git] / term.c
diff --git a/term.c b/term.c
index db53c211482378f3ee2dfbbb5f5713c0c8263a35..d3b217745149e2f9741ddfe43a17c530440569a2 100644 (file)
--- a/term.c
+++ b/term.c
@@ -1,7 +1,7 @@
-/*     $Id: term.c,v 1.211 2013/12/22 23:34:13 schwarze Exp $ */
+/*     $Id: term.c,v 1.217 2014/03/13 19:23:50 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -120,7 +120,12 @@ term_flushln(struct termp *p)
         * First, establish the maximum columns of "visible" content.
         * This is usually the difference between the right-margin and
         * an indentation, but can be, for tagged lists or columns, a
-        * small set of values. 
+        * small set of values.
+        *
+        * The following unsigned-signed subtractions look strange,
+        * but they are actually correct.  If the int p->overstep
+        * is negative, it gets sign extended.  Subtracting that
+        * very large size_t effectively adds a small number to dv.
         */
        assert  (p->rmargin >= p->offset);
        dv     = p->rmargin - p->offset;
@@ -174,9 +179,17 @@ term_flushln(struct termp *p)
                        /* Regular word. */
                        /* Break at the hyphen point if we overrun. */
                        if (vend > vis && vend < bp && 
-                                       ASCII_HYPH == p->buf[j])
+                           (ASCII_HYPH == p->buf[j] ||
+                            ASCII_BREAK == p->buf[j]))
                                jhy = j;
 
+                       /*
+                        * Hyphenation now decided, put back a real
+                        * hyphen such that we get the correct width.
+                        */
+                       if (ASCII_HYPH == p->buf[j])
+                               p->buf[j] = '-';
+
                        vend += (*p->width)(p, p->buf[j]);
                }
 
@@ -199,7 +212,11 @@ term_flushln(struct termp *p)
                        if (0 < ntab)
                                vbl += ntab * p->tabwidth;
 
-                       /* Remove the p->overstep width. */
+                       /*
+                        * Remove the p->overstep width.
+                        * Again, if p->overstep is negative,
+                        * sign extension does the right thing.
+                        */
 
                        bp += (size_t)p->overstep;
                        p->overstep = 0;
@@ -224,6 +241,8 @@ term_flushln(struct termp *p)
                                vbl += (*p->width)(p, ' ');
                                continue;
                        }
+                       if (ASCII_BREAK == p->buf[i])
+                               continue;
 
                        /*
                         * Now we definitely know there will be
@@ -236,12 +255,6 @@ term_flushln(struct termp *p)
                                vbl = 0;
                        }
 
-                       if (ASCII_HYPH == p->buf[i]) {
-                               (*p->letter)(p, '-');
-                               p->viscol += (*p->width)(p, '-');
-                               continue;
-                       }
-
                        (*p->letter)(p, p->buf[i]);
                        if (8 == p->buf[i])
                                p->viscol -= (*p->width)(p, p->buf[i-1]);
@@ -275,8 +288,10 @@ term_flushln(struct termp *p)
                 * If we have overstepped the margin, temporarily move
                 * it to the right and flag the rest of the line to be
                 * shorter.
+                * If there is a request to keep the columns together,
+                * allow negative overstep when the column is not full.
                 */
-               if (p->overstep < 0)
+               if (p->trailspace && p->overstep < 0)
                        p->overstep = 0;
                return;
 
@@ -396,6 +411,7 @@ term_fontpop(struct termp *p)
 void
 term_word(struct termp *p, const char *word)
 {
+       const char       nbrsp[2] = { ASCII_NBRSP, 0 };
        const char      *seq, *cp;
        char             c;
        int              sz, uc;
@@ -418,7 +434,7 @@ term_word(struct termp *p, const char *word)
        else
                p->flags |= TERMP_NOSPACE;
 
-       p->flags &= ~(TERMP_SENTENCE | TERMP_IGNDELIM);
+       p->flags &= ~TERMP_SENTENCE;
 
        while ('\0' != *word) {
                if ('\\' != *word) {
@@ -427,7 +443,15 @@ term_word(struct termp *p, const char *word)
                                word++;
                                continue;
                        }
-                       ssz = strcspn(word, "\\");
+                       if (TERMP_NBRWORD & p->flags) {
+                               if (' ' == *word) {
+                                       encode(p, nbrsp, 1);
+                                       word++;
+                                       continue;
+                               }
+                               ssz = strcspn(word, "\\ ");
+                       } else
+                               ssz = strcspn(word, "\\");
                        encode(p, word, ssz);
                        word += (int)ssz;
                        continue;
@@ -502,6 +526,7 @@ term_word(struct termp *p, const char *word)
                        break;
                }
        }
+       p->flags &= ~TERMP_NBRWORD;
 }
 
 static void
@@ -623,7 +648,8 @@ term_strlen(const struct termp *p, const char *cp)
        int              ssz, skip, c;
        const char      *seq, *rhs;
        enum mandoc_esc  esc;
-       static const char rej[] = { '\\', ASCII_HYPH, ASCII_NBRSP, '\0' };
+       static const char rej[] = { '\\', ASCII_NBRSP, ASCII_HYPH,
+                       ASCII_BREAK, '\0' };
 
        /*
         * Account for escaped sequences within string length
@@ -638,7 +664,6 @@ term_strlen(const struct termp *p, const char *cp)
                for (i = 0; i < rsz; i++)
                        sz += cond_width(p, *cp++, &skip);
 
-               c = 0;
                switch (*cp) {
                case ('\\'):
                        cp++;
@@ -712,6 +737,8 @@ term_strlen(const struct termp *p, const char *cp)
                case (ASCII_HYPH):
                        sz += cond_width(p, '-', &skip);
                        cp++;
+                       /* FALLTHROUGH */
+               case (ASCII_BREAK):
                        break;
                default:
                        break;