[BACK]Return to tbl_term.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Diff for /mandoc/tbl_term.c between version 1.66 and 1.72

version 1.66, 2018/12/12 21:54:35 version 1.72, 2019/07/01 22:56:24
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011-2018 Ingo Schwarze <schwarze@openbsd.org>   * Copyright (c) 2011-2019 Ingo Schwarze <schwarze@openbsd.org>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 46  static void tbl_fill_border(struct termp *, int, size_
Line 46  static void tbl_fill_border(struct termp *, int, size_
 static  void    tbl_fill_char(struct termp *, char, size_t);  static  void    tbl_fill_char(struct termp *, char, size_t);
 static  void    tbl_fill_string(struct termp *, const char *, size_t);  static  void    tbl_fill_string(struct termp *, const char *, size_t);
 static  void    tbl_hrule(struct termp *, const struct tbl_span *,  static  void    tbl_hrule(struct termp *, const struct tbl_span *,
                         const struct tbl_span *, int);                          const struct tbl_span *, const struct tbl_span *,
                           int);
 static  void    tbl_literal(struct termp *, const struct tbl_dat *,  static  void    tbl_literal(struct termp *, const struct tbl_dat *,
                         const struct roffcol *);                          const struct roffcol *);
 static  void    tbl_number(struct termp *, const struct tbl_opts *,  static  void    tbl_number(struct termp *, const struct tbl_opts *,
Line 163  term_tbl(struct termp *tp, const struct tbl_span *sp)
Line 164  term_tbl(struct termp *tp, const struct tbl_span *sp)
         const struct tbl_cell   *cp, *cpn, *cpp, *cps;          const struct tbl_cell   *cp, *cpn, *cpp, *cps;
         const struct tbl_dat    *dp;          const struct tbl_dat    *dp;
         static size_t            offset;          static size_t            offset;
           size_t                   save_offset;
         size_t                   coloff, tsz;          size_t                   coloff, tsz;
         int                      hspans, ic, more;          int                      hspans, ic, more;
         int                      dvert, fc, horiz, line, uvert;          int                      dvert, fc, horiz, lhori, rhori, uvert;
   
         /* Inhibit printing of spaces: we do padding ourselves. */          /* Inhibit printing of spaces: we do padding ourselves. */
   
         tp->flags |= TERMP_NOSPACE | TERMP_NONOSPACE;          tp->flags |= TERMP_NOSPACE | TERMP_NONOSPACE;
           save_offset = tp->tcol->offset;
   
         /*          /*
          * The first time we're invoked for a given table block,           * The first time we're invoked for a given table block,
Line 211  term_tbl(struct termp *tp, const struct tbl_span *sp)
Line 214  term_tbl(struct termp *tp, const struct tbl_span *sp)
                                 tsz += tp->tbl.cols[sp->opts->cols - 1].width;                                  tsz += tp->tbl.cols[sp->opts->cols - 1].width;
                         if (offset + tsz > tp->tcol->rmargin)                          if (offset + tsz > tp->tcol->rmargin)
                                 tsz -= 1;                                  tsz -= 1;
                         tp->tcol->offset = offset + tp->tcol->rmargin > tsz ?                          offset = offset + tp->tcol->rmargin > tsz ?
                             (offset + tp->tcol->rmargin - tsz) / 2 : 0;                              (offset + tp->tcol->rmargin - tsz) / 2 : 0;
                           tp->tcol->offset = offset;
                 }                  }
   
                 /* Horizontal frame at the start of boxed tables. */                  /* Horizontal frame at the start of boxed tables. */
   
                 if (tp->enc == TERMENC_ASCII &&                  if (tp->enc == TERMENC_ASCII &&
                     sp->opts->opts & TBL_OPT_DBOX)                      sp->opts->opts & TBL_OPT_DBOX)
                         tbl_hrule(tp, NULL, sp, TBL_OPT_DBOX);                          tbl_hrule(tp, NULL, sp, sp, TBL_OPT_DBOX);
                 if (sp->opts->opts & (TBL_OPT_DBOX | TBL_OPT_BOX))                  if (sp->opts->opts & (TBL_OPT_DBOX | TBL_OPT_BOX))
                         tbl_hrule(tp, NULL, sp, TBL_OPT_BOX);                          tbl_hrule(tp, NULL, sp, sp, TBL_OPT_BOX);
         }          }
   
         /* Set up the columns. */          /* Set up the columns. */
   
         tp->flags |= TERMP_MULTICOL;          tp->flags |= TERMP_MULTICOL;
           tp->tcol->offset = offset;
         horiz = 0;          horiz = 0;
         switch (sp->pos) {          switch (sp->pos) {
         case TBL_SPAN_HORIZ:          case TBL_SPAN_HORIZ:
Line 321  term_tbl(struct termp *tp, const struct tbl_span *sp)
Line 326  term_tbl(struct termp *tp, const struct tbl_span *sp)
                     (horiz || (IS_HORIZ(sp->layout->first) &&                      (horiz || (IS_HORIZ(sp->layout->first) &&
                       !IS_HORIZ(sp->prev->layout->first))))                        !IS_HORIZ(sp->prev->layout->first))))
                         uvert = sp->prev->layout->vert;                          uvert = sp->prev->layout->vert;
                 line = sp->pos == TBL_SPAN_DHORIZ ||                  rhori = sp->pos == TBL_SPAN_DHORIZ ||
                       (sp->first != NULL && sp->first->pos == TBL_DATA_DHORIZ) ||
                     sp->layout->first->pos == TBL_CELL_DHORIZ ? 2 :                      sp->layout->first->pos == TBL_CELL_DHORIZ ? 2 :
                     sp->pos == TBL_SPAN_HORIZ ||                      sp->pos == TBL_SPAN_HORIZ ||
                       (sp->first != NULL && sp->first->pos == TBL_DATA_HORIZ) ||
                     sp->layout->first->pos == TBL_CELL_HORIZ ? 1 : 0;                      sp->layout->first->pos == TBL_CELL_HORIZ ? 1 : 0;
                 fc = BUP * uvert + BDOWN * dvert + BRIGHT * line;                  fc = BUP * uvert + BDOWN * dvert + BRIGHT * rhori;
                 if (uvert > 0 || dvert > 0 || (horiz && sp->opts->lvert)) {                  if (uvert > 0 || dvert > 0 || (horiz && sp->opts->lvert)) {
                         (*tp->advance)(tp, tp->tcols->offset);                          (*tp->advance)(tp, tp->tcols->offset);
                         tp->viscol = tp->tcol->offset;                          tp->viscol = tp->tcol->offset;
Line 336  term_tbl(struct termp *tp, const struct tbl_span *sp)
Line 343  term_tbl(struct termp *tp, const struct tbl_span *sp)
   
                 more = 0;                  more = 0;
                 if (horiz)                  if (horiz)
                         tbl_hrule(tp, sp->prev, sp, 0);                          tbl_hrule(tp, sp->prev, sp, sp->next, 0);
                 else {                  else {
                         cp = sp->layout->first;                          cp = sp->layout->first;
                         cpn = sp->next == NULL ? NULL :                          cpn = sp->next == NULL ? NULL :
Line 398  term_tbl(struct termp *tp, const struct tbl_span *sp)
Line 405  term_tbl(struct termp *tp, const struct tbl_span *sp)
                                         cpn = cpn->next;                                          cpn = cpn->next;
                                 }                                  }
   
                                   lhori = (cp != NULL &&
                                        cp->pos == TBL_CELL_DHORIZ) ||
                                       (dp != NULL &&
                                        dp->pos == TBL_DATA_DHORIZ) ? 2 :
                                       (cp != NULL &&
                                        cp->pos == TBL_CELL_HORIZ) ||
                                       (dp != NULL &&
                                        dp->pos == TBL_DATA_HORIZ) ? 1 : 0;
   
                                 /*                                  /*
                                  * Skip later cells in a span,                                   * Skip later cells in a span,
                                  * figure out whether to start a span,                                   * figure out whether to start a span,
Line 450  term_tbl(struct termp *tp, const struct tbl_span *sp)
Line 466  term_tbl(struct termp *tp, const struct tbl_span *sp)
                                 }                                  }
                                 while (tp->viscol < tp->tcol->rmargin +                                  while (tp->viscol < tp->tcol->rmargin +
                                     tp->tbl.cols[ic].spacing / 2)                                      tp->tbl.cols[ic].spacing / 2)
                                         tbl_direct_border(tp, fc, 1);                                          tbl_direct_border(tp,
                                               BHORIZ * lhori, 1);
   
                                 if (tp->tcol + 1 == tp->tcols + tp->lasttcol)                                  if (tp->tcol + 1 == tp->tcols + tp->lasttcol)
                                         continue;                                          continue;
   
                                 if (cp != NULL) {                                  if (cp != NULL)
                                         switch (cp->pos) {  
                                         case TBL_CELL_HORIZ:  
                                                 fc = BLEFT;  
                                                 break;  
                                         case TBL_CELL_DHORIZ:  
                                                 fc = BLEFT * 2;  
                                                 break;  
                                         default:  
                                                 fc = 0;  
                                                 break;  
                                         }  
                                         cp = cp->next;                                          cp = cp->next;
                                 }  
                                 if (cp != NULL) {                                  rhori = (cp != NULL &&
                                         switch (cp->pos) {                                       cp->pos == TBL_CELL_DHORIZ) ||
                                         case TBL_CELL_HORIZ:                                      (dp != NULL &&
                                                 fc += BRIGHT;                                       dp->pos == TBL_DATA_DHORIZ) ? 2 :
                                                 break;                                      (cp != NULL &&
                                         case TBL_CELL_DHORIZ:                                       cp->pos == TBL_CELL_HORIZ) ||
                                                 fc += BRIGHT * 2;                                      (dp != NULL &&
                                                 break;                                       dp->pos == TBL_DATA_HORIZ) ? 1 : 0;
                                         default:  
                                                 break;  
                                         }  
                                 }  
                                 if (tp->tbl.cols[ic].spacing)                                  if (tp->tbl.cols[ic].spacing)
                                         tbl_direct_border(tp, fc +                                          tbl_direct_border(tp,
                                               BLEFT * lhori + BRIGHT * rhori +
                                             BUP * uvert + BDOWN * dvert, 1);                                              BUP * uvert + BDOWN * dvert, 1);
   
                                 if (tp->enc == TERMENC_UTF8)                                  if (tp->enc == TERMENC_UTF8)
                                         uvert = dvert = 0;                                          uvert = dvert = 0;
   
                                 if (fc != 0) {  
                                         if (cp != NULL &&  
                                             cp->pos == TBL_CELL_HORIZ)  
                                                 fc = BHORIZ;  
                                         else if (cp != NULL &&  
                                             cp->pos == TBL_CELL_DHORIZ)  
                                                 fc = BHORIZ * 2;  
                                         else  
                                                 fc = 0;  
                                 }  
                                 if (tp->tbl.cols[ic].spacing > 2 &&                                  if (tp->tbl.cols[ic].spacing > 2 &&
                                     (uvert > 1 || dvert > 1 || fc != 0))                                      (uvert > 1 || dvert > 1 || rhori))
                                         tbl_direct_border(tp, fc +                                          tbl_direct_border(tp,
                                               BHORIZ * rhori +
                                             BUP * (uvert > 1) +                                              BUP * (uvert > 1) +
                                             BDOWN * (dvert > 1), 1);                                              BDOWN * (dvert > 1), 1);
                         }                          }
Line 524  term_tbl(struct termp *tp, const struct tbl_span *sp)
Line 519  term_tbl(struct termp *tp, const struct tbl_span *sp)
                     (horiz || (IS_HORIZ(sp->layout->last) &&                      (horiz || (IS_HORIZ(sp->layout->last) &&
                      !IS_HORIZ(sp->prev->layout->last))))                       !IS_HORIZ(sp->prev->layout->last))))
                         uvert = sp->prev->layout->last->vert;                          uvert = sp->prev->layout->last->vert;
                 line = sp->pos == TBL_SPAN_DHORIZ ||                  lhori = sp->pos == TBL_SPAN_DHORIZ ||
                       (sp->last != NULL &&
                        sp->last->pos == TBL_DATA_DHORIZ &&
                        sp->last->layout->col + 1 == sp->opts->cols) ||
                     (sp->layout->last->pos == TBL_CELL_DHORIZ &&                      (sp->layout->last->pos == TBL_CELL_DHORIZ &&
                      sp->layout->last->col + 1 == sp->opts->cols) ? 2 :                       sp->layout->last->col + 1 == sp->opts->cols) ? 2 :
                     sp->pos == TBL_SPAN_HORIZ ||                      sp->pos == TBL_SPAN_HORIZ ||
                       (sp->last != NULL &&
                        sp->last->pos == TBL_DATA_HORIZ &&
                        sp->last->layout->col + 1 == sp->opts->cols) ||
                     (sp->layout->last->pos == TBL_CELL_HORIZ &&                      (sp->layout->last->pos == TBL_CELL_HORIZ &&
                      sp->layout->last->col + 1 == sp->opts->cols) ? 1 : 0;                       sp->layout->last->col + 1 == sp->opts->cols) ? 1 : 0;
                 fc = BUP * uvert + BDOWN * dvert + BLEFT * line;                  fc = BUP * uvert + BDOWN * dvert + BLEFT * lhori;
                 if (uvert > 0 || dvert > 0 || (horiz && sp->opts->rvert)) {                  if (uvert > 0 || dvert > 0 || (horiz && sp->opts->rvert)) {
                         if (horiz == 0 && (IS_HORIZ(sp->layout->last) == 0 ||                          if (horiz == 0 && (IS_HORIZ(sp->layout->last) == 0 ||
                             sp->layout->last->col + 1 < sp->opts->cols)) {                              sp->layout->last->col + 1 < sp->opts->cols)) {
                                 tp->tcol++;                                  tp->tcol++;
                                 (*tp->advance)(tp,                                  do {
                                     tp->tcol->offset > tp->viscol ?                                          tbl_direct_border(tp,
                                     tp->tcol->offset - tp->viscol : 1);                                              BHORIZ * lhori, 1);
                                   } while (tp->viscol < tp->tcol->offset);
                         }                          }
                         tbl_direct_border(tp, fc, 1);                          tbl_direct_border(tp, fc, 1);
                 }                  }
Line 556  term_tbl(struct termp *tp, const struct tbl_span *sp)
Line 558  term_tbl(struct termp *tp, const struct tbl_span *sp)
         tp->tcol->rmargin = tp->maxrmargin;          tp->tcol->rmargin = tp->maxrmargin;
         if (sp->next == NULL) {          if (sp->next == NULL) {
                 if (sp->opts->opts & (TBL_OPT_DBOX | TBL_OPT_BOX)) {                  if (sp->opts->opts & (TBL_OPT_DBOX | TBL_OPT_BOX)) {
                         tbl_hrule(tp, sp, NULL, TBL_OPT_BOX);                          tbl_hrule(tp, sp, sp, NULL, TBL_OPT_BOX);
                         tp->skipvsp = 1;                          tp->skipvsp = 1;
                 }                  }
                 if (tp->enc == TERMENC_ASCII &&                  if (tp->enc == TERMENC_ASCII &&
                     sp->opts->opts & TBL_OPT_DBOX) {                      sp->opts->opts & TBL_OPT_DBOX) {
                         tbl_hrule(tp, sp, NULL, TBL_OPT_DBOX);                          tbl_hrule(tp, sp, sp, NULL, TBL_OPT_DBOX);
                         tp->skipvsp = 2;                          tp->skipvsp = 2;
                 }                  }
                 assert(tp->tbl.cols);                  assert(tp->tbl.cols);
                 free(tp->tbl.cols);                  free(tp->tbl.cols);
                 tp->tbl.cols = NULL;                  tp->tbl.cols = NULL;
                 tp->tcol->offset = offset;  
         } else if (horiz == 0 && sp->opts->opts & TBL_OPT_ALLBOX &&          } else if (horiz == 0 && sp->opts->opts & TBL_OPT_ALLBOX &&
             (sp->next == NULL || sp->next->pos == TBL_SPAN_DATA ||              (sp->next == NULL || sp->next->pos == TBL_SPAN_DATA ||
              sp->next->next != NULL))               sp->next->next != NULL))
                 tbl_hrule(tp, sp, sp->next, TBL_OPT_ALLBOX);                  tbl_hrule(tp, sp, sp, sp->next, TBL_OPT_ALLBOX);
   
           tp->tcol->offset = save_offset;
         tp->flags &= ~TERMP_NONOSPACE;          tp->flags &= ~TERMP_NONOSPACE;
 }  }
   
 static void  static void
 tbl_hrule(struct termp *tp, const struct tbl_span *spp,  tbl_hrule(struct termp *tp, const struct tbl_span *spp,
     const struct tbl_span *spn, int flags)      const struct tbl_span *sp, const struct tbl_span *spn, int flags)
 {  {
         const struct tbl_cell   *cpp;    /* Layout cell above this line. */          const struct tbl_cell   *cpp;    /* Layout cell above this line. */
           const struct tbl_cell   *cp;     /* Layout cell in this line. */
         const struct tbl_cell   *cpn;    /* Layout cell below this line. */          const struct tbl_cell   *cpn;    /* Layout cell below this line. */
         const struct tbl_dat    *dpn;    /* Data cell below this line. */          const struct tbl_dat    *dpn;    /* Data cell below this line. */
         const struct roffcol    *col;    /* Contains width and spacing. */          const struct roffcol    *col;    /* Contains width and spacing. */
Line 591  tbl_hrule(struct termp *tp, const struct tbl_span *spp
Line 594  tbl_hrule(struct termp *tp, const struct tbl_span *spp
         int                      uw, dw; /* Vertical line widths. */          int                      uw, dw; /* Vertical line widths. */
   
         cpp = spp == NULL ? NULL : spp->layout->first;          cpp = spp == NULL ? NULL : spp->layout->first;
           cp  = sp  == NULL ? NULL : sp->layout->first;
         cpn = spn == NULL ? NULL : spn->layout->first;          cpn = spn == NULL ? NULL : spn->layout->first;
         dpn = NULL;          dpn = NULL;
         if (spn != NULL) {          if (spn != NULL) {
Line 599  tbl_hrule(struct termp *tp, const struct tbl_span *spp
Line 603  tbl_hrule(struct termp *tp, const struct tbl_span *spp
                 else if (spn->next != NULL)                  else if (spn->next != NULL)
                         dpn = spn->next->first;                          dpn = spn->next->first;
         }          }
         opts = spn == NULL ? spp->opts->opts : spn->opts->opts;          opts = sp->opts->opts;
         bw = opts & TBL_OPT_DBOX ? (tp->enc == TERMENC_UTF8 ? 2 : 1) :          bw = opts & TBL_OPT_DBOX ? (tp->enc == TERMENC_UTF8 ? 2 : 1) :
             opts & (TBL_OPT_BOX | TBL_OPT_ALLBOX) ? 1 : 0;              opts & (TBL_OPT_BOX | TBL_OPT_ALLBOX) ? 1 : 0;
         hw = flags == TBL_OPT_DBOX || flags == TBL_OPT_BOX ? bw :          hw = flags == TBL_OPT_DBOX || flags == TBL_OPT_BOX ? bw :
             spn->pos == TBL_SPAN_DHORIZ ? 2 : 1;              sp->pos == TBL_SPAN_DHORIZ ? 2 : 1;
   
         /* Print the left end of the line. */          /* Print the left end of the line. */
   
Line 618  tbl_hrule(struct termp *tp, const struct tbl_span *spp
Line 622  tbl_hrule(struct termp *tp, const struct tbl_span *spp
                     (spp == NULL || cpn == NULL ||                      (spp == NULL || cpn == NULL ||
                      cpn->pos != TBL_CELL_DOWN ? BRIGHT * hw : 0), 1);                       cpn->pos != TBL_CELL_DOWN ? BRIGHT * hw : 0), 1);
   
           col = tp->tbl.cols;
         for (;;) {          for (;;) {
                 col = tp->tbl.cols + (cpn == NULL ? cpp->col : cpn->col);                  if (cp == NULL)
                           col++;
                   else
                           col = tp->tbl.cols + cp->col;
   
                 /* Print the horizontal line inside this column. */                  /* Print the horizontal line inside this column. */
   
                 lw = cpp == NULL || cpn == NULL ||                  lw = cpp == NULL || cpn == NULL ||
                     (cpn->pos != TBL_CELL_DOWN &&                      (cpn->pos != TBL_CELL_DOWN &&
                      (dpn == NULL || strcmp(dpn->string, "\\^") != 0))                       (dpn == NULL || dpn->string == NULL ||
                         strcmp(dpn->string, "\\^") != 0))
                     ? hw : 0;                      ? hw : 0;
                 tbl_direct_border(tp, BHORIZ * lw,                  tbl_direct_border(tp, BHORIZ * lw,
                     col->width + col->spacing / 2);                      col->width + col->spacing / 2);
Line 644  tbl_hrule(struct termp *tp, const struct tbl_span *spp
Line 653  tbl_hrule(struct termp *tp, const struct tbl_span *spp
                                         uw = 1;                                          uw = 1;
                         }                          }
                         cpp = cpp->next;                          cpp = cpp->next;
                 }                  } else if (spp != NULL && opts & TBL_OPT_ALLBOX)
                           uw = 1;
                   if (cp != NULL)
                           cp = cp->next;
                 if (cpn != NULL) {                  if (cpn != NULL) {
                         if (flags != TBL_OPT_DBOX) {                          if (flags != TBL_OPT_DBOX) {
                                 dw = cpn->vert;                                  dw = cpn->vert;
Line 654  tbl_hrule(struct termp *tp, const struct tbl_span *spp
Line 666  tbl_hrule(struct termp *tp, const struct tbl_span *spp
                         cpn = cpn->next;                          cpn = cpn->next;
                         while (dpn != NULL && dpn->layout != cpn)                          while (dpn != NULL && dpn->layout != cpn)
                                 dpn = dpn->next;                                  dpn = dpn->next;
                 }                  } else if (spn != NULL && opts & TBL_OPT_ALLBOX)
                 if (cpp == NULL && cpn == NULL)                          dw = 1;
                   if (col + 1 == tp->tbl.cols + sp->opts->cols)
                         break;                          break;
   
                 /* Vertical lines do not cross spanned cells. */                  /* Vertical lines do not cross spanned cells. */
Line 669  tbl_hrule(struct termp *tp, const struct tbl_span *spp
Line 682  tbl_hrule(struct termp *tp, const struct tbl_span *spp
   
                 rw = cpp == NULL || cpn == NULL ||                  rw = cpp == NULL || cpn == NULL ||
                     (cpn->pos != TBL_CELL_DOWN &&                      (cpn->pos != TBL_CELL_DOWN &&
                      (dpn == NULL || strcmp(dpn->string, "\\^") != 0))                       (dpn == NULL || dpn->string == NULL ||
                         strcmp(dpn->string, "\\^") != 0))
                     ? hw : 0;                      ? hw : 0;
   
                 /* The line crossing at the end of this column. */                  /* The line crossing at the end of this column. */

Legend:
Removed from v.1.66  
changed lines
  Added in v.1.72

CVSweb