]> git.cameronkatri.com Git - mandoc.git/commitdiff
Do not handle vertical lines as additional tbl(7) columns,
authorIngo Schwarze <schwarze@openbsd.org>
Sun, 27 May 2012 17:54:54 +0000 (17:54 +0000)
committerIngo Schwarze <schwarze@openbsd.org>
Sun, 27 May 2012 17:54:54 +0000 (17:54 +0000)
instead save their properties with the following column.
This simplifies layout parsing and saves a lot of code
related to column handling.

At output time, print all white space and vertical lines
separating columns before printing the following column,
and none after printing the preceding column, considerably
simplifying white space handling and width calculations.

No functional change, but it saves 150 lines of code,
and it allows the next patch to tbl_term.c, tbl_literal().

"Please check them in and I'll look into them later!" kristaps@

mandoc.h
out.c
tbl_data.c
tbl_html.c
tbl_layout.c
tbl_term.c

index a784866d910669f3abb8c9884c408f8bb426f5ab..2665371f0fb7a0cd6111d15b13882f846e60d54b 100644 (file)
--- a/mandoc.h
+++ b/mandoc.h
@@ -1,4 +1,4 @@
-/*     $Id: mandoc.h,v 1.100 2012/05/27 17:48:57 schwarze Exp $ */
+/*     $Id: mandoc.h,v 1.101 2012/05/27 17:54:54 schwarze Exp $ */
 /*
  * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -175,20 +175,14 @@ struct    tbl {
        int               cols; /* number of columns */
 };
 
-enum   tbl_headt {
-       TBL_HEAD_DATA, /* plug in data from tbl_dat */
-       TBL_HEAD_VERT, /* vertical spacer */
-       TBL_HEAD_DVERT  /* double-vertical spacer */
-};
-
 /*
  * The head of a table specifies all of its columns.  When formatting a
  * tbl_span, iterate over these and plug in data from the tbl_span when
  * appropriate, using tbl_cell as a guide to placement.
  */
 struct tbl_head {
-       enum tbl_headt    pos;
        int               ident; /* 0 <= unique id < cols */
+       int               vert; /* width of preceding vertical line */
        struct tbl_head  *next;
        struct tbl_head  *prev;
 };
@@ -203,8 +197,6 @@ enum        tbl_cellt {
        TBL_CELL_DOWN, /* ^ */
        TBL_CELL_HORIZ, /* _, - */
        TBL_CELL_DHORIZ, /* = */
-       TBL_CELL_VERT, /* | */
-       TBL_CELL_DVERT, /* || */
        TBL_CELL_MAX
 };
 
@@ -213,6 +205,7 @@ enum        tbl_cellt {
  */
 struct tbl_cell {
        struct tbl_cell  *next;
+       int               vert; /* width of preceding vertical line */
        enum tbl_cellt    pos;
        size_t            spacing;
        int               flags;
diff --git a/out.c b/out.c
index 8dbd68ac11ad7c4d3c14dd72befaf7ab73e353bb..6f41f3bccaab576973883b2790d340744678f833 100644 (file)
--- a/out.c
+++ b/out.c
@@ -1,4 +1,4 @@
-/*     $Id: out.c,v 1.43 2011/09/20 23:05:49 schwarze Exp $ */
+/*     $Id: out.c,v 1.44 2012/05/27 17:54:54 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
@@ -178,25 +178,6 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp)
                        tblcalc_data(tbl, col, sp->tbl, dp);
                }
        }
-
-       /* 
-        * Calculate width of the spanners.  These get one space for a
-        * vertical line, two for a double-vertical line. 
-        */
-
-       for ( ; hp; hp = hp->next) {
-               col = &tbl->cols[hp->ident];
-               switch (hp->pos) {
-               case (TBL_HEAD_VERT):
-                       col->width = (*tbl->len)(1, tbl->arg);
-                       break;
-               case (TBL_HEAD_DVERT):
-                       col->width = (*tbl->len)(2, tbl->arg);
-                       break;
-               default:
-                       break;
-               }
-       }
 }
 
 static void
index 129695d8bb96b0da97bc1d54643f5a3e0408ca1a..3b4096487a9eb61f3f73dfd03c0d9940195a4873 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: tbl_data.c,v 1.24 2011/03/20 16:02:05 kristaps Exp $ */
+/*     $Id: tbl_data.c,v 1.25 2012/05/27 17:54:54 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
@@ -49,13 +49,11 @@ data(struct tbl_node *tbl, struct tbl_span *dp,
                cp = dp->layout->first;
 
        /* 
-        * Skip over spanners and vertical lines to data formats, since
+        * Skip over spanners, since
         * we want to match data with data layout cells in the header.
         */
 
-       while (cp && (TBL_CELL_VERT == cp->pos || 
-                               TBL_CELL_DVERT == cp->pos ||
-                               TBL_CELL_SPAN == cp->pos))
+       while (cp && TBL_CELL_SPAN == cp->pos)
                cp = cp->next;
 
        /*
index 8e7dc05de0db4613fcb28ca093f9813d0df64698..6b8ced716b11133d7ecf64ddece203b98febf61c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: tbl_html.c,v 1.9 2011/09/18 14:14:15 schwarze Exp $ */
+/*     $Id: tbl_html.c,v 1.10 2012/05/27 17:54:54 schwarze Exp $ */
 /*
  * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -119,20 +119,12 @@ print_tbl(struct html *h, const struct tbl_span *sp)
                        print_stagq(h, tt);
                        print_otag(h, TAG_TD, 0, NULL);
 
-                       switch (hp->pos) {
-                       case (TBL_HEAD_VERT):
-                               /* FALLTHROUGH */
-                       case (TBL_HEAD_DVERT):
-                               continue;
-                       case (TBL_HEAD_DATA):
-                               if (NULL == dp)
-                                       break;
-                               if (TBL_CELL_DOWN != dp->layout->pos)
-                                       if (dp->string)
-                                               print_text(h, dp->string);
-                               dp = dp->next;
+                       if (NULL == dp)
                                break;
-                       }
+                       if (TBL_CELL_DOWN != dp->layout->pos)
+                               if (dp->string)
+                                       print_text(h, dp->string);
+                       dp = dp->next;
                }
                break;
        }
index 7601f146cad60fd627cc7fcb69d4cbf2e070d590..6cce977fa2e74f9a8fd33a852818a61dc8a58d8b 100644 (file)
@@ -1,6 +1,7 @@
-/*     $Id: tbl_layout.c,v 1.22 2011/09/18 14:14:15 schwarze Exp $ */
+/*     $Id: tbl_layout.c,v 1.23 2012/05/27 17:54:54 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2012 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
@@ -51,8 +52,7 @@ static        const struct tbl_phrase keys[KEYS_MAX] = {
        { '^',           TBL_CELL_DOWN },
        { '-',           TBL_CELL_HORIZ },
        { '_',           TBL_CELL_HORIZ },
-       { '=',           TBL_CELL_DHORIZ },
-       { '|',           TBL_CELL_VERT }
+       { '=',           TBL_CELL_DHORIZ }
 };
 
 static int              mods(struct tbl_node *, struct tbl_cell *, 
@@ -60,10 +60,8 @@ static       int              mods(struct tbl_node *, struct tbl_cell *,
 static int              cell(struct tbl_node *, struct tbl_row *, 
                                int, const char *, int *);
 static void             row(struct tbl_node *, int, const char *, int *);
-static struct tbl_cell *cell_alloc(struct tbl_node *, 
-                               struct tbl_row *, enum tbl_cellt);
-static void             head_adjust(const struct tbl_cell *, 
-                               struct tbl_head *);
+static struct tbl_cell *cell_alloc(struct tbl_node *, struct tbl_row *,
+                               enum tbl_cellt, int vert);
 
 static int
 mods(struct tbl_node *tbl, struct tbl_cell *cp, 
@@ -80,10 +78,6 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp,
        case (TBL_CELL_HORIZ):
                /* FALLTHROUGH */
        case (TBL_CELL_DHORIZ):
-               /* FALLTHROUGH */
-       case (TBL_CELL_VERT):
-               /* FALLTHROUGH */
-       case (TBL_CELL_DVERT):
                return(1);
        default:
                break;
@@ -214,10 +208,17 @@ static int
 cell(struct tbl_node *tbl, struct tbl_row *rp, 
                int ln, const char *p, int *pos)
 {
-       int              i;
+       int              vert, i;
        enum tbl_cellt   c;
 
-       /* Parse the column position (`r', `R', `|', ...). */
+       /* Handle vertical lines. */
+
+       for (vert = 0; '|' == p[*pos]; ++*pos)
+               vert++;
+       while (' ' == p[*pos])
+               (*pos)++;
+
+       /* Parse the column position (`c', `l', `r', ...). */
 
        for (i = 0; i < KEYS_MAX; i++)
                if (tolower((unsigned char)p[*pos]) == keys[i].name)
@@ -246,8 +247,6 @@ cell(struct tbl_node *tbl, struct tbl_row *rp,
                        return(0);
                } else if (rp->last)
                        switch (rp->last->pos) {
-                       case (TBL_CELL_VERT):
-                       case (TBL_CELL_DVERT):
                        case (TBL_CELL_HORIZ):
                        case (TBL_CELL_DHORIZ):
                                mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse,
@@ -270,25 +269,16 @@ cell(struct tbl_node *tbl, struct tbl_row *rp,
 
        (*pos)++;
 
-       /* Extra check for the double-vertical. */
-
-       if (TBL_CELL_VERT == c && '|' == p[*pos]) {
-               (*pos)++;
-               c = TBL_CELL_DVERT;
-       } 
-       
        /* Disallow adjacent spacers. */
 
-       if (rp->last && (TBL_CELL_VERT == c || TBL_CELL_DVERT == c) &&
-                       (TBL_CELL_VERT == rp->last->pos || 
-                        TBL_CELL_DVERT == rp->last->pos)) {
+       if (vert > 2) {
                mandoc_msg(MANDOCERR_TBLLAYOUT, tbl->parse, ln, *pos - 1, NULL);
                return(0);
        }
 
        /* Allocate cell then parse its modifiers. */
 
-       return(mods(tbl, cell_alloc(tbl, rp, c), ln, p, pos));
+       return(mods(tbl, cell_alloc(tbl, rp, c, vert), ln, p, pos));
 }
 
 
@@ -308,11 +298,11 @@ row:      /*
         */
 
        rp = mandoc_calloc(1, sizeof(struct tbl_row));
-       if (tbl->last_row) {
+       if (tbl->last_row)
                tbl->last_row->next = rp;
-               tbl->last_row = rp;
-       } else
-               tbl->last_row = tbl->first_row = rp;
+       else
+               tbl->first_row = rp;
+       tbl->last_row = rp;
 
 cell:
        while (isspace((unsigned char)p[*pos]))
@@ -357,7 +347,8 @@ tbl_layout(struct tbl_node *tbl, int ln, const char *p)
 }
 
 static struct tbl_cell *
-cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos)
+cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos,
+               int vert)
 {
        struct tbl_cell *p, *pp;
        struct tbl_head *h, *hp;
@@ -365,108 +356,35 @@ cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos)
        p = mandoc_calloc(1, sizeof(struct tbl_cell));
 
        if (NULL != (pp = rp->last)) {
-               rp->last->next = p;
-               rp->last = p;
-       } else
-               rp->last = rp->first = p;
+               pp->next = p;
+               h = pp->head->next;
+       } else {
+               rp->first = p;
+               h = tbl->first_head;
+       }
+       rp->last = p;
 
        p->pos = pos;
+       p->vert = vert;
 
-       /*
-        * This is a little bit complicated.  Here we determine the
-        * header the corresponds to a cell.  We add headers dynamically
-        * when need be or re-use them, otherwise.  As an example, given
-        * the following:
-        *
-        *      1  c || l 
-        *      2  | c | l
-        *      3  l l
-        *      3  || c | l |.
-        *
-        * We first add the new headers (as there are none) in (1); then
-        * in (2) we insert the first spanner (as it doesn't match up
-        * with the header); then we re-use the prior data headers,
-        * skipping over the spanners; then we re-use everything and add
-        * a last spanner.  Note that VERT headers are made into DVERT
-        * ones.
-        */
-
-       h = pp ? pp->head->next : tbl->first_head;
+       /* Re-use header. */
 
        if (h) {
-               /* Re-use data header. */
-               if (TBL_HEAD_DATA == h->pos && 
-                               (TBL_CELL_VERT != p->pos &&
-                                TBL_CELL_DVERT != p->pos)) {
-                       p->head = h;
-                       return(p);
-               }
-
-               /* Re-use spanner header. */
-               if (TBL_HEAD_DATA != h->pos && 
-                               (TBL_CELL_VERT == p->pos ||
-                                TBL_CELL_DVERT == p->pos)) {
-                       head_adjust(p, h);
-                       p->head = h;
-                       return(p);
-               }
-
-               /* Right-shift headers with a new spanner. */
-               if (TBL_HEAD_DATA == h->pos && 
-                               (TBL_CELL_VERT == p->pos ||
-                                TBL_CELL_DVERT == p->pos)) {
-                       hp = mandoc_calloc(1, sizeof(struct tbl_head));
-                       hp->ident = tbl->opts.cols++;
-                       hp->prev = h->prev;
-                       if (h->prev)
-                               h->prev->next = hp;
-                       if (h == tbl->first_head)
-                               tbl->first_head = hp;
-                       h->prev = hp;
-                       hp->next = h;
-                       head_adjust(p, hp);
-                       p->head = hp;
-                       return(p);
-               }
-
-               if (NULL != (h = h->next)) {
-                       head_adjust(p, h);
-                       p->head = h;
-                       return(p);
-               }
-
-               /* Fall through to default case... */
+               p->head = h;
+               return(p);
        }
 
        hp = mandoc_calloc(1, sizeof(struct tbl_head));
        hp->ident = tbl->opts.cols++;
+       hp->vert = vert;
 
        if (tbl->last_head) {
                hp->prev = tbl->last_head;
                tbl->last_head->next = hp;
-               tbl->last_head = hp;
        } else
-               tbl->last_head = tbl->first_head = hp;
+               tbl->first_head = hp;
+       tbl->last_head = hp;
 
-       head_adjust(p, hp);
        p->head = hp;
        return(p);
 }
-
-static void
-head_adjust(const struct tbl_cell *cellp, struct tbl_head *head)
-{
-       if (TBL_CELL_VERT != cellp->pos &&
-                       TBL_CELL_DVERT != cellp->pos) {
-               head->pos = TBL_HEAD_DATA;
-               return;
-       }
-
-       if (TBL_CELL_VERT == cellp->pos)
-               if (TBL_HEAD_DVERT != head->pos)
-                       head->pos = TBL_HEAD_VERT;
-
-       if (TBL_CELL_DVERT == cellp->pos)
-               head->pos = TBL_HEAD_DVERT;
-}
-
index f1928f02cb20d74e286eda3e1cd93a180dbbb94a..644f6cecbd1bf3ed3092c4c011002b715de9f744 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: tbl_term.c,v 1.21 2011/09/20 23:05:49 schwarze Exp $ */
+/*     $Id: tbl_term.c,v 1.22 2012/05/27 17:54:54 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
@@ -126,50 +126,24 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
                dp = sp->first;
                spans = 0;
                for (hp = sp->head; hp; hp = hp->next) {
+
                        /* 
                         * If the current data header is invoked during
                         * a spanner ("spans" > 0), don't emit anything
                         * at all.
                         */
-                       switch (hp->pos) {
-                       case (TBL_HEAD_VERT):
-                               /* FALLTHROUGH */
-                       case (TBL_HEAD_DVERT):
-                               if (spans <= 0)
-                                       tbl_vrule(tp, hp);
-                               continue;
-                       case (TBL_HEAD_DATA):
-                               break;
-                       }
 
                        if (--spans >= 0)
                                continue;
 
-                       /*
-                        * All cells get a leading blank, except the
-                        * first one and those after double rulers.
-                        */
+                       /* Separate columns. */
 
-                       if (hp->prev && TBL_HEAD_DVERT != hp->prev->pos)
-                               tbl_char(tp, ASCII_NBRSP, 1);
+                       if (NULL != hp->prev)
+                               tbl_vrule(tp, hp);
 
                        col = &tp->tbl.cols[hp->ident];
                        tbl_data(tp, sp->tbl, dp, col);
 
-                       /* No trailing blanks. */
-
-                       if (NULL == hp->next)
-                               break;
-
-                       /*
-                        * Add another blank between cells,
-                        * or two when there is no vertical ruler.
-                        */
-
-                       tbl_char(tp, ASCII_NBRSP,
-                           TBL_HEAD_VERT  == hp->next->pos ||
-                           TBL_HEAD_DVERT == hp->next->pos ? 1 : 2);
-
                        /* 
                         * Go to the next data cell and assign the
                         * number of subsequent spans, if applicable.
@@ -222,17 +196,14 @@ tbl_rulewidth(struct termp *tp, const struct tbl_head *hp)
        size_t           width;
 
        width = tp->tbl.cols[hp->ident].width;
-       if (TBL_HEAD_DATA == hp->pos) {
-               /* Account for leading blanks. */
-               if (hp->prev && TBL_HEAD_DVERT != hp->prev->pos)
-                       width++;
-               /* Account for trailing blanks. */
-               width++;
-               if (hp->next &&
-                   TBL_HEAD_VERT  != hp->next->pos &&
-                   TBL_HEAD_DVERT != hp->next->pos)
-                       width++;
-       }
+
+       /* Account for leading blanks. */
+       if (hp->prev)
+               width += 2 - hp->vert;
+
+       /* Account for trailing blank. */
+       width++;
+
        return(width);
 }
 
@@ -250,10 +221,11 @@ tbl_hrule(struct termp *tp, const struct tbl_span *sp)
        if (TBL_SPAN_DHORIZ == sp->pos)
                c = '=';
 
-       for (hp = sp->head; hp; hp = hp->next)
-               tbl_char(tp,
-                   TBL_HEAD_DATA == hp->pos ? c : '+',
-                   tbl_rulewidth(tp, hp));
+       for (hp = sp->head; hp; hp = hp->next) {
+               if (hp->prev && hp->vert)
+                       tbl_char(tp, '+', hp->vert);
+               tbl_char(tp, c, tbl_rulewidth(tp, hp));
+       }
 }
 
 /*
@@ -268,10 +240,11 @@ tbl_hframe(struct termp *tp, const struct tbl_span *sp, int outer)
        const struct tbl_head *hp;
 
        term_word(tp, "+");
-       for (hp = sp->head; hp; hp = hp->next)
-               tbl_char(tp,
-                   outer || TBL_HEAD_DATA == hp->pos ? '-' : '+',
-                   tbl_rulewidth(tp, hp));
+       for (hp = sp->head; hp; hp = hp->next) {
+               if (hp->prev && hp->vert)
+                       tbl_char(tp, (outer ? '-' : '+'), hp->vert);
+               tbl_char(tp, '-', tbl_rulewidth(tp, hp));
+       }
        term_word(tp, "+");
        term_flushln(tp);
 }
@@ -338,16 +311,11 @@ static void
 tbl_vrule(struct termp *tp, const struct tbl_head *hp)
 {
 
-       switch (hp->pos) {
-       case (TBL_HEAD_VERT):
-               term_word(tp, "|");
-               break;
-       case (TBL_HEAD_DVERT):
-               term_word(tp, "||");
-               break;
-       default:
-               break;
-       }
+       tbl_char(tp, ASCII_NBRSP, 1);
+       if (0 < hp->vert)
+               tbl_char(tp, '|', hp->vert);
+       if (2 > hp->vert)
+               tbl_char(tp, ASCII_NBRSP, 2 - hp->vert);
 }
 
 static void