[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.62 and 1.66

version 1.62, 2018/11/28 04:47:51 version 1.66, 2018/12/12 21:54:35
Line 26 
Line 26 
 #include <string.h>  #include <string.h>
   
 #include "mandoc.h"  #include "mandoc.h"
   #include "tbl.h"
 #include "out.h"  #include "out.h"
 #include "term.h"  #include "term.h"
   
 #define IS_HORIZ(cp)    ((cp)->pos == TBL_CELL_HORIZ || \  #define IS_HORIZ(cp)    ((cp)->pos == TBL_CELL_HORIZ || \
                          (cp)->pos == TBL_CELL_DHORIZ)                           (cp)->pos == TBL_CELL_DHORIZ)
   
 /* Flags for tbl_hrule(). */  
 #define HRULE_DBOX      (1 << 0)  /* Top and bottom, ASCII mode only. */  
 #define HRULE_DATA      (1 << 1)  /* In the middle of the table. */  
 #define HRULE_DOWN      (1 << 2)  /* Allow downward branches. */  
 #define HRULE_UP        (1 << 3)  /* Allow upward branches. */  
 #define HRULE_ENDS      (1 << 4)  /* Also generate left and right ends. */  
   
   
 static  size_t  term_tbl_len(size_t, void *);  static  size_t  term_tbl_len(size_t, void *);
 static  size_t  term_tbl_strlen(const char *, void *);  static  size_t  term_tbl_strlen(const char *, void *);
 static  size_t  term_tbl_sulen(const struct roffsu *, void *);  static  size_t  term_tbl_sulen(const struct roffsu *, void *);
Line 51  static void tbl_direct_border(struct termp *, int, siz
Line 45  static void tbl_direct_border(struct termp *, int, siz
 static  void    tbl_fill_border(struct termp *, int, size_t);  static  void    tbl_fill_border(struct termp *, int, size_t);
 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 *, int);  static  void    tbl_hrule(struct termp *, 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 224  term_tbl(struct termp *tp, const struct tbl_span *sp)
Line 219  term_tbl(struct termp *tp, const struct tbl_span *sp)
   
                 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, HRULE_DBOX | HRULE_ENDS);                          tbl_hrule(tp, NULL, 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, sp, HRULE_DOWN | HRULE_ENDS);                          tbl_hrule(tp, NULL, sp, TBL_OPT_BOX);
         }          }
   
         /* Set up the columns. */          /* Set up the columns. */
Line 341  term_tbl(struct termp *tp, const struct tbl_span *sp)
Line 336  term_tbl(struct termp *tp, const struct tbl_span *sp)
   
                 more = 0;                  more = 0;
                 if (horiz)                  if (horiz)
                         tbl_hrule(tp, sp, HRULE_DATA | HRULE_DOWN | HRULE_UP);                          tbl_hrule(tp, sp->prev, sp, 0);
                 else {                  else {
                         cp = sp->layout->first;                          cp = sp->layout->first;
                         cpn = sp->next == NULL ? NULL :                          cpn = sp->next == NULL ? NULL :
Line 437  term_tbl(struct termp *tp, const struct tbl_span *sp)
Line 432  term_tbl(struct termp *tp, const struct tbl_span *sp)
                                  * but not after the last column.                                   * but not after the last column.
                                  */                                   */
   
                                 if (fc == 0 && ((uvert == 0 && dvert == 0 &&                                  if (fc == 0 &&
                                      (cp->next == NULL ||                                      ((uvert == 0 && dvert == 0 &&
                                         cp != NULL && (cp->next == NULL ||
                                       !IS_HORIZ(cp->next))) ||                                        !IS_HORIZ(cp->next))) ||
                                     tp->tcol + 1 == tp->tcols + tp->lasttcol)) {                                       tp->tcol + 1 ==
                                         cp = cp->next;                                        tp->tcols + tp->lasttcol)) {
                                           if (cp != NULL)
                                                   cp = cp->next;
                                         continue;                                          continue;
                                 }                                  }
   
Line 558  term_tbl(struct termp *tp, const struct tbl_span *sp)
Line 556  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, HRULE_UP | HRULE_ENDS);                          tbl_hrule(tp, 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, HRULE_DBOX | HRULE_ENDS);                          tbl_hrule(tp, sp, NULL, TBL_OPT_DBOX);
                         tp->skipvsp = 2;                          tp->skipvsp = 2;
                 }                  }
                 assert(tp->tbl.cols);                  assert(tp->tbl.cols);
Line 573  term_tbl(struct termp *tp, const struct tbl_span *sp)
Line 571  term_tbl(struct termp *tp, const struct tbl_span *sp)
         } 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,                  tbl_hrule(tp, sp, sp->next, TBL_OPT_ALLBOX);
                     HRULE_DATA | HRULE_DOWN | HRULE_UP | HRULE_ENDS);  
   
         tp->flags &= ~TERMP_NONOSPACE;          tp->flags &= ~TERMP_NONOSPACE;
 }  }
   
 static void  static void
 tbl_hrule(struct termp *tp, const struct tbl_span *sp, int flags)  tbl_hrule(struct termp *tp, const struct tbl_span *spp,
       const struct tbl_span *spn, int flags)
 {  {
         const struct tbl_cell *cp, *cpn, *cpp;          const struct tbl_cell   *cpp;    /* Layout cell above this line. */
         const struct roffcol *col;          const struct tbl_cell   *cpn;    /* Layout cell below this line. */
         int cross, dvert, line, linewidth, uvert;          const struct tbl_dat    *dpn;    /* Data cell below this line. */
           const struct roffcol    *col;    /* Contains width and spacing. */
           int                      opts;   /* For the table as a whole. */
           int                      bw;     /* Box line width. */
           int                      hw;     /* Horizontal line width. */
           int                      lw, rw; /* Left and right line widths. */
           int                      uw, dw; /* Vertical line widths. */
   
         cp = sp->layout->first;          cpp = spp == NULL ? NULL : spp->layout->first;
         cpn = cpp = NULL;          cpn = spn == NULL ? NULL : spn->layout->first;
         if (flags & HRULE_DATA) {          dpn = NULL;
                 linewidth = sp->pos == TBL_SPAN_DHORIZ ? 2 : 1;          if (spn != NULL) {
                 cpn = sp->next == NULL ? NULL : sp->next->layout->first;                  if (spn->pos == TBL_SPAN_DATA)
                 if (cpn == cp)                          dpn = spn->first;
                         cpn = NULL;                  else if (spn->next != NULL)
         } else                          dpn = spn->next->first;
                 linewidth = tp->enc == TERMENC_UTF8 &&          }
                     sp->opts->opts & TBL_OPT_DBOX ? 2 : 1;          opts = spn == NULL ? spp->opts->opts : spn->opts->opts;
           bw = opts & TBL_OPT_DBOX ? (tp->enc == TERMENC_UTF8 ? 2 : 1) :
               opts & (TBL_OPT_BOX | TBL_OPT_ALLBOX) ? 1 : 0;
           hw = flags == TBL_OPT_DBOX || flags == TBL_OPT_BOX ? bw :
               spn->pos == TBL_SPAN_DHORIZ ? 2 : 1;
   
           /* Print the left end of the line. */
   
         if (tp->viscol == 0) {          if (tp->viscol == 0) {
                 (*tp->advance)(tp, tp->tcols->offset);                  (*tp->advance)(tp, tp->tcols->offset);
                 tp->viscol = tp->tcols->offset;                  tp->viscol = tp->tcols->offset;
         }          }
         if (flags & HRULE_ENDS)          if (flags != 0)
                 tbl_direct_border(tp, linewidth * (BRIGHT +                  tbl_direct_border(tp,
                     (flags & (HRULE_UP | HRULE_DBOX) ? BUP : 0) +                      (spp == NULL ? 0 : BUP * bw) +
                     (flags & (HRULE_DOWN | HRULE_DBOX) ? BDOWN : 0)), 1);                      (spn == NULL ? 0 : BDOWN * bw) +
         else {                      (spp == NULL || cpn == NULL ||
                 cpp = sp->prev == NULL ? NULL : sp->prev->layout->first;                       cpn->pos != TBL_CELL_DOWN ? BRIGHT * hw : 0), 1);
                 if (cpp == cp)  
                         cpp = NULL;  
         }  
         for (;;) {          for (;;) {
                 col = tp->tbl.cols + cp->col;                  col = tp->tbl.cols + (cpn == NULL ? cpp->col : cpn->col);
                 line = cpn == NULL || cpn->pos != TBL_CELL_DOWN ?  
                     BHORIZ * linewidth : 0;                  /* Print the horizontal line inside this column. */
                 tbl_direct_border(tp, line, col->width + col->spacing / 2);  
                 uvert = dvert = 0;                  lw = cpp == NULL || cpn == NULL ||
                 if (flags & HRULE_UP &&                      (cpn->pos != TBL_CELL_DOWN &&
                     (tp->enc == TERMENC_ASCII || sp->pos == TBL_SPAN_DATA ||                       (dpn == NULL || strcmp(dpn->string, "\\^") != 0))
                      (sp->prev != NULL && sp->prev->layout == sp->layout)))                      ? hw : 0;
                         uvert = cp->vert;                  tbl_direct_border(tp, BHORIZ * lw,
                 if (flags & HRULE_DOWN)                      col->width + col->spacing / 2);
                         dvert = cp->vert;  
                 if ((cp = cp->next) == NULL)                  /*
                         break;                   * Figure out whether a vertical line is crossing
                    * at the end of this column,
                    * and advance to the next column.
                    */
   
                   uw = dw = 0;
                 if (cpp != NULL) {                  if (cpp != NULL) {
                         if (uvert < cpp->vert)                          if (flags != TBL_OPT_DBOX) {
                                 uvert = cpp->vert;                                  uw = cpp->vert;
                                   if (uw == 0 && opts & TBL_OPT_ALLBOX)
                                           uw = 1;
                           }
                         cpp = cpp->next;                          cpp = cpp->next;
                 }                  }
                 if (cpn != NULL) {                  if (cpn != NULL) {
                         if (dvert < cpn->vert)                          if (flags != TBL_OPT_DBOX) {
                                 dvert = cpn->vert;                                  dw = cpn->vert;
                                   if (dw == 0 && opts & TBL_OPT_ALLBOX)
                                           dw = 1;
                           }
                         cpn = cpn->next;                          cpn = cpn->next;
                           while (dpn != NULL && dpn->layout != cpn)
                                   dpn = dpn->next;
                 }                  }
                 if (sp->opts->opts & TBL_OPT_ALLBOX) {                  if (cpp == NULL && cpn == NULL)
                         if (flags & HRULE_UP && uvert == 0)                          break;
                                 uvert = 1;  
                         if (flags & HRULE_DOWN && dvert == 0)                  /* Vertical lines do not cross spanned cells. */
                                 dvert = 1;  
                 }                  if (cpp != NULL && cpp->pos == TBL_CELL_SPAN)
                 cross = BHORIZ * linewidth + BUP * uvert + BDOWN * dvert;                          uw = 0;
                   if (cpn != NULL && cpn->pos == TBL_CELL_SPAN)
                           dw = 0;
   
                   /* The horizontal line inside the next column. */
   
                   rw = cpp == NULL || cpn == NULL ||
                       (cpn->pos != TBL_CELL_DOWN &&
                        (dpn == NULL || strcmp(dpn->string, "\\^") != 0))
                       ? hw : 0;
   
                   /* The line crossing at the end of this column. */
   
                 if (col->spacing)                  if (col->spacing)
                         tbl_direct_border(tp, cross, 1);                          tbl_direct_border(tp, BLEFT * lw +
                               BRIGHT * rw + BUP * uw + BDOWN * dw, 1);
   
                   /*
                    * In ASCII output, a crossing may print two characters.
                    */
   
                   if (tp->enc != TERMENC_ASCII || (uw < 2 && dw < 2))
                           uw = dw = 0;
                 if (col->spacing > 2)                  if (col->spacing > 2)
                         tbl_direct_border(tp, tp->enc == TERMENC_ASCII &&                          tbl_direct_border(tp,
                             (uvert > 1 || dvert > 1) ? cross : line, 1);                              BHORIZ * rw + BUP * uw + BDOWN * dw, 1);
   
                   /* Padding before the start of the next column. */
   
                 if (col->spacing > 4)                  if (col->spacing > 4)
                         tbl_direct_border(tp, line, (col->spacing - 3) / 2);                          tbl_direct_border(tp,
                               BHORIZ * rw, (col->spacing - 3) / 2);
         }          }
         if (flags & HRULE_ENDS) {  
                 tbl_direct_border(tp, linewidth * (BLEFT +          /* Print the right end of the line. */
                     (flags & (HRULE_UP | HRULE_DBOX) ? BUP : 0) +  
                     (flags & (HRULE_DOWN | HRULE_DBOX) ? BDOWN : 0)), 1);          if (flags != 0) {
                   tbl_direct_border(tp,
                       (spp == NULL ? 0 : BUP * bw) +
                       (spn == NULL ? 0 : BDOWN * bw) +
                       (spp == NULL || spn == NULL ||
                        spn->layout->last->pos != TBL_CELL_DOWN ?
                        BLEFT * hw : 0), 1);
                 (*tp->endline)(tp);                  (*tp->endline)(tp);
                 tp->viscol = 0;                  tp->viscol = 0;
         }          }

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

CVSweb