Print this page
9718 update mandoc to 1.14.4

@@ -1,6 +1,6 @@
-/*      $Id: eqn_term.c,v 1.13 2017/07/08 14:51:04 schwarze Exp $ */
+/*      $Id: eqn_term.c,v 1.17 2017/08/23 21:56:20 schwarze Exp $ */
 /*
  * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any

@@ -18,10 +18,11 @@
 #include "config.h"
 
 #include <sys/types.h>
 
 #include <assert.h>
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "mandoc.h"

@@ -49,10 +50,11 @@
 
 static void
 eqn_box(struct termp *p, const struct eqn_box *bp)
 {
         const struct eqn_box *child;
+        const char *cp;
         int delim;
 
         /* Delimiters around this box? */
 
         if ((bp->type == EQN_LIST && bp->expectargs > 1) ||

@@ -65,11 +67,20 @@
             /* Nested over, sub, sup, from, to. */
             (bp->type == EQN_SUBEXPR && bp->pos != EQNPOS_SQRT &&
              ((bp->parent->type == EQN_LIST && bp->expectargs == 1) ||
               (bp->parent->type == EQN_SUBEXPR &&
                bp->pos != EQNPOS_SQRT)))))) {
-                if (bp->parent->type == EQN_SUBEXPR && bp->prev != NULL)
+                if ((bp->parent->type == EQN_SUBEXPR && bp->prev != NULL) ||
+                    (bp->type == EQN_LIST &&
+                     bp->first != NULL &&
+                     bp->first->type != EQN_PILE &&
+                     bp->first->type != EQN_MATRIX &&
+                     bp->prev != NULL &&
+                     (bp->prev->type == EQN_LIST ||
+                      (bp->prev->type == EQN_TEXT &&
+                       (*bp->prev->text == '\\' ||
+                        isalpha((unsigned char)*bp->prev->text))))))
                         p->flags |= TERMP_NOSPACE;
                 term_word(p, bp->left != NULL ? bp->left : "(");
                 p->flags |= TERMP_NOSPACE;
                 delim = 1;
         } else

@@ -78,12 +89,21 @@
         /* Handle Fonts and text. */
 
         if (bp->font != EQNFONT_NONE)
                 term_fontpush(p, fontmap[(int)bp->font]);
 
-        if (bp->text != NULL)
+        if (bp->text != NULL) {
+                if (strchr("!\"'),.:;?]}", *bp->text) != NULL)
+                        p->flags |= TERMP_NOSPACE;
                 term_word(p, bp->text);
+                if ((cp = strchr(bp->text, '\0')) > bp->text &&
+                    (strchr("\"'([{", cp[-1]) != NULL ||
+                     (bp->prev == NULL && (cp[-1] == '-' ||
+                      (cp >= bp->text + 5 &&
+                       strcmp(cp - 5, "\\[mi]") == 0)))))
+                        p->flags |= TERMP_NOSPACE;
+        }
 
         /* Special box types. */
 
         if (bp->pos == EQNPOS_SQRT) {
                 term_word(p, "sqrt");

@@ -96,13 +116,13 @@
                 eqn_box(p, child);
                 p->flags |= TERMP_NOSPACE;
                 term_word(p, bp->pos == EQNPOS_OVER ? "/" :
                     (bp->pos == EQNPOS_SUP ||
                      bp->pos == EQNPOS_TO) ? "^" : "_");
-                p->flags |= TERMP_NOSPACE;
                 child = child->next;
                 if (child != NULL) {
+                        p->flags |= TERMP_NOSPACE;
                         eqn_box(p, child);
                         if (bp->pos == EQNPOS_FROMTO ||
                             bp->pos == EQNPOS_SUBSUP) {
                                 p->flags |= TERMP_NOSPACE;
                                 term_word(p, "^");