]> git.cameronkatri.com Git - mandoc.git/blobdiff - term.c
Support relative arguments to .ll (increase or decrease line length).
[mandoc.git] / term.c
diff --git a/term.c b/term.c
index 3420c70c4629105446ba2a532f0b02024faa4390..29c4fcb8914a92ae3e617fa420c17f21acb7b7ba 100644 (file)
--- a/term.c
+++ b/term.c
@@ -1,7 +1,7 @@
-/*     $Id: term.c,v 1.212 2013/12/23 02:20:09 schwarze Exp $ */
+/*     $Id: term.c,v 1.219 2014/03/30 21:28:01 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
 
 #include <assert.h>
 #include <ctype.h>
-#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "mandoc.h"
+#include "mandoc_aux.h"
 #include "out.h"
 #include "term.h"
 #include "main.h"
@@ -179,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]);
                }
 
@@ -233,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
@@ -245,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]);
@@ -407,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;
@@ -429,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) {
@@ -438,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;
@@ -513,6 +526,7 @@ term_word(struct termp *p, const char *word)
                        break;
                }
        }
+       p->flags &= ~TERMP_NBRWORD;
 }
 
 static void
@@ -609,6 +623,36 @@ encode(struct termp *p, const char *word, size_t sz)
        }
 }
 
+void
+term_setwidth(struct termp *p, const char *wstr)
+{
+       struct roffsu    su;
+       size_t           width;
+       int              iop;
+
+       if (NULL != wstr) {
+               switch (*wstr) {
+               case ('+'):
+                       iop = 1;
+                       wstr++;
+                       break;
+               case ('-'):
+                       iop = -1;
+                       wstr++;
+                       break;
+               default:
+                       iop = 0;
+                       break;
+               }
+               if ( ! a2roffsu(wstr, &su, SCALE_MAX)) {
+                       wstr = NULL;
+                       iop = 0;
+               }
+       }
+       width = (NULL != wstr) ? term_hspan(p, &su) : 0;
+       (*p->setwidth)(p, iop, width);
+}
+
 size_t
 term_len(const struct termp *p, size_t sz)
 {
@@ -634,7 +678,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
@@ -649,7 +694,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++;
@@ -723,6 +767,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;