]> git.cameronkatri.com Git - mandoc.git/blobdiff - tbl_layout.c
Tedu support for the -xsh4.2 argument to the mdoc(7) .St macro
[mandoc.git] / tbl_layout.c
index ed9acc9c0a5af24313498a186e2d50ad45af5c02..171a8dbb1b4904e834be975d0c3eeabef105c92b 100644 (file)
@@ -1,7 +1,8 @@
-/*     $Id: tbl_layout.c,v 1.38 2015/02/10 11:03:13 schwarze Exp $ */
+/*     $Id: tbl_layout.c,v 1.50 2021/08/10 12:55:04 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2012, 2014, 2015, 2017, 2020, 2021
+ *               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 <sys/types.h>
 
 #include <ctype.h>
+#include <stdint.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
 
-#include "mandoc.h"
 #include "mandoc_aux.h"
+#include "mandoc.h"
+#include "tbl.h"
 #include "libmandoc.h"
-#include "libroff.h"
+#include "tbl_int.h"
 
 struct tbl_phrase {
        char             name;
@@ -62,6 +66,10 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
                int ln, const char *p, int *pos)
 {
        char            *endptr;
+       unsigned long    spacing;
+       size_t           sz;
+       int              isz;
+       enum mandoc_esc  fontesc;
 
 mod:
        while (p[*pos] == ' ' || p[*pos] == '\t')
@@ -82,22 +90,25 @@ mod:
                        (*pos)++;
                        goto mod;
                }
-               mandoc_msg(MANDOCERR_TBLLAYOUT_PAR, tbl->parse,
-                   ln, *pos, NULL);
+               mandoc_msg(MANDOCERR_TBLLAYOUT_PAR, ln, *pos, NULL);
                return;
        }
 
        /* Parse numerical spacing from modifier string. */
 
        if (isdigit((unsigned char)p[*pos])) {
-               cp->spacing = strtoull(p + *pos, &endptr, 10);
+               if ((spacing = strtoul(p + *pos, &endptr, 10)) > 9)
+                       mandoc_msg(MANDOCERR_TBLLAYOUT_SPC, ln, *pos,
+                           "%lu", spacing);
+               else
+                       cp->spacing = spacing;
                *pos = endptr - p;
                goto mod;
        }
 
        switch (tolower((unsigned char)p[(*pos)++])) {
        case 'b':
-               cp->flags |= TBL_CELL_BOLD;
+               cp->font = ESCAPE_FONTBOLD;
                goto mod;
        case 'd':
                cp->flags |= TBL_CELL_BALIGN;
@@ -108,14 +119,12 @@ mod:
        case 'f':
                break;
        case 'i':
-               cp->flags |= TBL_CELL_ITALIC;
+               cp->font = ESCAPE_FONTITALIC;
                goto mod;
        case 'm':
-               mandoc_msg(MANDOCERR_TBLLAYOUT_MOD, tbl->parse,
-                   ln, *pos, "m");
+               mandoc_msg(MANDOCERR_TBLLAYOUT_MOD, ln, *pos, "m");
                goto mod;
        case 'p':
-               /* FALLTHROUGH */
        case 'v':
                if (p[*pos] == '-' || p[*pos] == '+')
                        (*pos)++;
@@ -128,7 +137,22 @@ mod:
        case 'u':
                cp->flags |= TBL_CELL_UP;
                goto mod;
-       case 'w':  /* XXX for now, ignore minimal column width */
+       case 'w':
+               sz = 0;
+               if (p[*pos] == '(') {
+                       (*pos)++;
+                       while (p[*pos + sz] != '\0' && p[*pos + sz] != ')')
+                               sz++;
+               } else
+                       while (isdigit((unsigned char)p[*pos + sz]))
+                               sz++;
+               if (sz) {
+                       free(cp->wstr);
+                       cp->wstr = mandoc_strndup(p + *pos, sz);
+                       *pos += sz;
+                       if (p[*pos] == ')')
+                               (*pos)++;
+               }
                goto mod;
        case 'x':
                cp->flags |= TBL_CELL_WMAX;
@@ -141,51 +165,42 @@ mod:
                        cp->vert++;
                else
                        mandoc_msg(MANDOCERR_TBLLAYOUT_VERT,
-                           tbl->parse, ln, *pos - 1, NULL);
+                           ln, *pos - 1, NULL);
                goto mod;
        default:
-               mandoc_vmsg(MANDOCERR_TBLLAYOUT_CHAR, tbl->parse,
+               mandoc_msg(MANDOCERR_TBLLAYOUT_CHAR,
                    ln, *pos - 1, "%c", p[*pos - 1]);
                goto mod;
        }
 
+       while (p[*pos] == ' ' || p[*pos] == '\t')
+               (*pos)++;
+
        /* Ignore parenthised font names for now. */
 
        if (p[*pos] == '(')
                goto mod;
 
-       /* Support only one-character font-names for now. */
-
-       if (p[*pos] == '\0' || (p[*pos + 1] != ' ' && p[*pos + 1] != '.')) {
-               mandoc_vmsg(MANDOCERR_FT_BAD, tbl->parse,
+       isz = 0;
+       if (p[*pos] != '\0')
+               isz++;
+       if (strchr(" \t.", p[*pos + isz]) == NULL)
+               isz++;
+       
+       fontesc = mandoc_font(p + *pos, isz);
+
+       switch (fontesc) {
+       case ESCAPE_FONTPREV:
+       case ESCAPE_ERROR:
+               mandoc_msg(MANDOCERR_FT_BAD,
                    ln, *pos, "TS %s", p + *pos - 1);
-               if (p[*pos] != '\0')
-                       (*pos)++;
-               if (p[*pos] != '\0')
-                       (*pos)++;
-               goto mod;
-       }
-
-       switch (p[(*pos)++]) {
-       case '3':
-               /* FALLTHROUGH */
-       case 'B':
-               cp->flags |= TBL_CELL_BOLD;
-               goto mod;
-       case '2':
-               /* FALLTHROUGH */
-       case 'I':
-               cp->flags |= TBL_CELL_ITALIC;
-               goto mod;
-       case '1':
-               /* FALLTHROUGH */
-       case 'R':
-               goto mod;
+               break;
        default:
-               mandoc_vmsg(MANDOCERR_FT_BAD, tbl->parse,
-                   ln, *pos - 1, "TS f%c", p[*pos - 1]);
-               goto mod;
+               cp->font = fontesc;
+               break;
        }
+       *pos += isz;
+       goto mod;
 }
 
 static void
@@ -203,7 +218,7 @@ cell(struct tbl_node *tbl, struct tbl_row *rp,
                                rp->vert++;
                        else
                                mandoc_msg(MANDOCERR_TBLLAYOUT_VERT,
-                                   tbl->parse, ln, *pos, NULL);
+                                   ln, *pos, NULL);
                }
                (*pos)++;
        }
@@ -222,7 +237,7 @@ again:
                        break;
 
        if (i == KEYS_MAX) {
-               mandoc_vmsg(MANDOCERR_TBLLAYOUT_CHAR, tbl->parse,
+               mandoc_msg(MANDOCERR_TBLLAYOUT_CHAR,
                    ln, *pos, "%c", p[*pos]);
                (*pos)++;
                goto again;
@@ -233,14 +248,12 @@ again:
 
        if (c == TBL_CELL_SPAN) {
                if (rp->last == NULL)
-                       mandoc_msg(MANDOCERR_TBLLAYOUT_SPAN,
-                           tbl->parse, ln, *pos, NULL);
+                       mandoc_msg(MANDOCERR_TBLLAYOUT_SPAN, ln, *pos, NULL);
                else if (rp->last->pos == TBL_CELL_HORIZ ||
                    rp->last->pos == TBL_CELL_DHORIZ)
                        c = rp->last->pos;
        } else if (c == TBL_CELL_DOWN && rp == tbl->first_row)
-               mandoc_msg(MANDOCERR_TBLLAYOUT_DOWN,
-                   tbl->parse, ln, *pos, NULL);
+               mandoc_msg(MANDOCERR_TBLLAYOUT_DOWN, ln, *pos, NULL);
 
        (*pos)++;
 
@@ -283,9 +296,11 @@ tbl_layout(struct tbl_node *tbl, int ln, const char *p, int pos)
                        }
                        if (tbl->first_row->first == NULL) {
                                mandoc_msg(MANDOCERR_TBLLAYOUT_NONE,
-                                   tbl->parse, ln, pos, NULL);
+                                   ln, pos, NULL);
                                cell_alloc(tbl, tbl->first_row,
                                    TBL_CELL_LEFT);
+                               if (tbl->opts.lvert < tbl->first_row->vert)
+                                       tbl->opts.lvert = tbl->first_row->vert;
                                return;
                        }
 
@@ -308,6 +323,7 @@ tbl_layout(struct tbl_node *tbl, int ln, const char *p, int pos)
                                    rp->next->first == NULL) {
                                        free(rp->next);
                                        rp->next = NULL;
+                                       tbl->last_row = rp;
                                }
                        }
                        return;
@@ -342,6 +358,8 @@ cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos)
        struct tbl_cell *p, *pp;
 
        p = mandoc_calloc(1, sizeof(*p));
+       p->spacing = SIZE_MAX;
+       p->font = ESCAPE_FONTROMAN;
        p->pos = pos;
 
        if ((pp = rp->last) != NULL) {
@@ -354,5 +372,5 @@ cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos)
        if (tbl->opts.cols <= p->col)
                tbl->opts.cols = p->col + 1;
 
-       return(p);
+       return p;
 }