]> git.cameronkatri.com Git - mandoc.git/blobdiff - tbl_term.c
Do not mistreat empty arguments to font alternating macros
[mandoc.git] / tbl_term.c
index e9497dd237009cddeab816b50c7fd24b948c4ca0..1276776668c988227cc09093b1191f0a958f0de7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: tbl_term.c,v 1.33 2015/01/27 05:21:45 schwarze Exp $ */
+/*     $Id: tbl_term.c,v 1.40 2015/03/06 15:48:53 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011, 2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -60,11 +60,11 @@ term_tbl_len(size_t sz, void *arg)
 void
 term_tbl(struct termp *tp, const struct tbl_span *sp)
 {
-       const struct tbl_head   *hp;
        const struct tbl_cell   *cp;
        const struct tbl_dat    *dp;
-       int                      horiz, spans, vert;
-       size_t                   rmargin, maxrmargin;
+       static size_t            offset;
+       size_t                   rmargin, maxrmargin, tsz;
+       int                      ic, horiz, spans, vert;
 
        rmargin = tp->rmargin;
        maxrmargin = tp->maxrmargin;
@@ -81,15 +81,28 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
         * calculate the table widths and decimal positions.
         */
 
-       if (sp->flags & TBL_SPAN_FIRST) {
-               term_flushln(tp);
-
+       if (tp->tbl.cols == NULL) {
                tp->tbl.len = term_tbl_len;
                tp->tbl.slen = term_tbl_strlen;
                tp->tbl.arg = tp;
 
                tblcalc(&tp->tbl, sp, rmargin - tp->offset);
 
+               /* Center the table as a whole. */
+
+               offset = tp->offset;
+               if (sp->opts->opts & TBL_OPT_CENTRE) {
+                       tsz = sp->opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX)
+                           ? 2 : !!sp->opts->lvert + !!sp->opts->rvert;
+                       for (ic = 0; ic < sp->opts->cols; ic++)
+                               tsz += tp->tbl.cols[ic].width + 3;
+                       tsz -= 3;
+                       if (offset + tsz > rmargin)
+                               tsz -= 1;
+                       tp->offset = (offset + rmargin > tsz) ?
+                           (offset + rmargin - tsz) / 2 : 0;
+               }
+
                /* Horizontal frame at the start of boxed tables. */
 
                if (sp->opts->opts & TBL_OPT_DBOX)
@@ -111,16 +124,14 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
 
        /*
         * Now print the actual data itself depending on the span type.
-        * Spanner spans get a horizontal rule; data spanners have their
-        * data printed by matching data to header.
+        * Match data cells to column numbers.
         */
 
        if (sp->pos == TBL_SPAN_DATA) {
-               /* Iterate over template headers. */
                cp = sp->layout->first;
                dp = sp->first;
                spans = 0;
-               for (hp = sp->head; hp != NULL; hp = hp->next) {
+               for (ic = 0; ic < sp->opts->cols; ic++) {
 
                        /*
                         * Remeber whether we need a vertical bar
@@ -134,8 +145,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
                         */
 
                        if (spans == 0) {
-                               tbl_data(tp, sp->opts, dp,
-                                   tp->tbl.cols + hp->ident);
+                               tbl_data(tp, sp->opts, dp, tp->tbl.cols + ic);
                                if (dp != NULL) {
                                        spans = dp->spans;
                                        dp = dp->next;
@@ -150,13 +160,13 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
                         * of spans and after the last cell.
                         */
 
-                       if (hp->next == NULL || spans)
+                       if (ic + 1 == sp->opts->cols || spans)
                                continue;
 
                        tbl_char(tp, ASCII_NBRSP, 1);
                        if (vert > 0)
                                tbl_char(tp, '|', vert);
-                       if (vert < 2 && hp->next != NULL)
+                       if (vert < 2)
                                tbl_char(tp, ASCII_NBRSP, 2 - vert);
                }
        } else if (horiz)
@@ -177,7 +187,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
         * existing table configuration and set it to NULL.
         */
 
-       if (sp->flags & TBL_SPAN_LAST) {
+       if (sp->next == NULL) {
                if (sp->opts->opts & (TBL_OPT_DBOX | TBL_OPT_BOX)) {
                        tbl_hrule(tp, sp, 1);
                        tp->skipvsp = 1;
@@ -189,12 +199,12 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
                assert(tp->tbl.cols);
                free(tp->tbl.cols);
                tp->tbl.cols = NULL;
+               tp->offset = offset;
        }
 
        tp->flags &= ~TERMP_NONOSPACE;
        tp->rmargin = rmargin;
        tp->maxrmargin = maxrmargin;
-
 }
 
 /*
@@ -220,7 +230,7 @@ tbl_hrule(struct termp *tp, const struct tbl_span *sp, int kind)
        if (c2 == c1)
                c2 = NULL;
        for (;;) {
-               tbl_char(tp, line, tp->tbl.cols[c1->head->ident].width + 1);
+               tbl_char(tp, line, tp->tbl.cols[c1->col].width + 1);
                vert = c1->vert;
                if ((c1 = c1->next) == NULL)
                         break;
@@ -246,11 +256,10 @@ tbl_data(struct termp *tp, const struct tbl_opts *opts,
        const struct roffcol *col)
 {
 
-       if (NULL == dp) {
+       if (dp == NULL) {
                tbl_char(tp, ASCII_NBRSP, col->width);
                return;
        }
-       assert(dp->layout);
 
        switch (dp->pos) {
        case TBL_DATA_NONE:
@@ -317,17 +326,16 @@ static void
 tbl_literal(struct termp *tp, const struct tbl_dat *dp,
                const struct roffcol *col)
 {
-       struct tbl_head         *hp;
-       size_t                   width, len, padl, padr;
-       int                      spans;
+       size_t           len, padl, padr, width;
+       int              ic, spans;
 
        assert(dp->string);
        len = term_strlen(tp, dp->string);
-
-       hp = dp->layout->head->next;
        width = col->width;
-       for (spans = dp->spans; spans--; hp = hp->next)
-               width += tp->tbl.cols[hp->ident].width + 3;
+       ic = dp->layout->col;
+       spans = dp->spans;
+       while (spans--)
+               width += tp->tbl.cols[++ic].width + 3;
 
        padr = width > len ? width - len : 0;
        padl = 0;
@@ -380,8 +388,7 @@ tbl_number(struct termp *tp, const struct tbl_opts *opts,
 
        psz = term_strlen(tp, buf);
 
-       if (NULL != (cp = strrchr(dp->string, opts->decimal))) {
-               buf[1] = '\0';
+       if ((cp = strrchr(dp->string, opts->decimal)) != NULL) {
                for (ssz = 0, i = 0; cp != &dp->string[i]; i++) {
                        buf[0] = dp->string[i];
                        ssz += term_strlen(tp, buf);
@@ -405,9 +412,9 @@ tbl_number(struct termp *tp, const struct tbl_opts *opts,
 static void
 tbl_word(struct termp *tp, const struct tbl_dat *dp)
 {
-       const void      *prev_font;
+       int              prev_font;
 
-       prev_font = term_fontq(tp);
+       prev_font = tp->fonti;
        if (dp->layout->flags & TBL_CELL_BOLD)
                term_fontpush(tp, TERMFONT_BOLD);
        else if (dp->layout->flags & TBL_CELL_ITALIC)