]> git.cameronkatri.com Git - mandoc.git/commitdiff
Considerably cleaned up list handling.
authorKristaps Dzonsons <kristaps@bsd.lv>
Wed, 4 Mar 2009 13:57:35 +0000 (13:57 +0000)
committerKristaps Dzonsons <kristaps@bsd.lv>
Wed, 4 Mar 2009 13:57:35 +0000 (13:57 +0000)
mdocterm.1
mdocterm.c
term.c
term.h
validate.c

index 1b293b23fcf29ea7aa990bddfee14ebf98d5a225..5164dd5e060ee1bb851636dbff8f7a059cf57849 100644 (file)
@@ -1,4 +1,4 @@
-.\" $Id: mdocterm.1,v 1.11 2009/03/03 22:17:19 kristaps Exp $
+.\" $Id: mdocterm.1,v 1.12 2009/03/04 13:57:35 kristaps Exp $
 .\"
 .\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
 .\"
 .\"
 .\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
 .\"
@@ -16,7 +16,7 @@
 .\" TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 .\" PERFORMANCE OF THIS SOFTWARE.
 .\"
 .\" TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 .\" PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: March 3 2009 $
+.Dd $Mdocdate: March 4 2009 $
 .Dt mdocmterm 1
 .Os
 .\" SECTION
 .Dt mdocmterm 1
 .Os
 .\" SECTION
@@ -258,4 +258,8 @@ displays only accept text contents.
 The
 .Sq \&Xo/Xc
 pair isn't supported (and never will be).
 The
 .Sq \&Xo/Xc
 pair isn't supported (and never will be).
+.It
+The
+.Sq \&Sm
+macro has no effect, yet.
 .El
 .El
index 9149a6d96d8a35a75f8eb60d5c1dd29321df292b..820edd5b61de087f366ce3cabff64dd7c4728639 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mdocterm.c,v 1.28 2009/03/03 22:17:19 kristaps Exp $ */
+/* $Id: mdocterm.c,v 1.29 2009/03/04 13:57:35 kristaps Exp $ */
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -189,8 +189,7 @@ main(int argc, char *argv[])
        if (NULL == (mdoc = mmain_mdoc(p)))
                mmain_exit(p, 1);
 
        if (NULL == (mdoc = mmain_mdoc(p)))
                mmain_exit(p, 1);
 
-       termp.maxrmargin = 78; /* XXX */
-       termp.rmargin = termp.maxrmargin;
+       termp.maxrmargin = termp.rmargin = 78; /* XXX */
        termp.maxcols = 1024;
        termp.offset = termp.col = 0;
        termp.flags = TERMP_NOSPACE;
        termp.maxcols = 1024;
        termp.offset = termp.col = 0;
        termp.flags = TERMP_NOSPACE;
@@ -317,7 +316,7 @@ flushln(struct termp *p)
                                putchar('\n');
                                for (j = 0; j < p->rmargin; j++)
                                        putchar(' ');
                                putchar('\n');
                                for (j = 0; j < p->rmargin; j++)
                                        putchar(' ');
-                               vis = p->rmargin;
+                               vis = p->offset;
                        } else if (vis + vsz > bp) 
                                warnx("word breaks right margin");
 
                        } else if (vis + vsz > bp) 
                                warnx("word breaks right margin");
 
diff --git a/term.c b/term.c
index 7888980b66f2aa8d14ce41c69f4c04a07af0f3ac..2236703ecd95cd1ee42bfadfdb411582f710a6f3 100644 (file)
--- a/term.c
+++ b/term.c
@@ -1,4 +1,4 @@
-/* $Id: term.c,v 1.38 2009/03/03 22:28:21 kristaps Exp $ */
+/* $Id: term.c,v 1.39 2009/03/04 13:57:35 kristaps Exp $ */
 /*
  * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
 /*
  * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -89,6 +89,7 @@ static        int               arg_getattr(int, size_t,
                                const struct mdoc_arg *);
 static size_t            arg_offset(const struct mdoc_arg *);
 static size_t            arg_width(const struct mdoc_arg *);
                                const struct mdoc_arg *);
 static size_t            arg_offset(const struct mdoc_arg *);
 static size_t            arg_width(const struct mdoc_arg *);
+static int               arg_listtype(const struct mdoc_node *);
 
 /*
  * What follows describes prefix and postfix operations for the abstract
 
 /*
  * What follows describes prefix and postfix operations for the abstract
@@ -308,6 +309,44 @@ arg_width(const struct mdoc_arg *arg)
 }
 
 
 }
 
 
+static int
+arg_listtype(const struct mdoc_node *n)
+{
+       const struct mdoc_block *bl;
+       int              i, len;
+
+       bl = &n->data.block;
+       len = (int)bl->argc;
+
+       for (i = 0; i < len; i++) 
+               switch (bl->argv[i].arg) {
+               case (MDOC_Bullet):
+                       /* FALLTHROUGH */
+               case (MDOC_Dash):
+                       /* FALLTHROUGH */
+               case (MDOC_Enum):
+                       /* FALLTHROUGH */
+               case (MDOC_Hyphen):
+                       /* FALLTHROUGH */
+               case (MDOC_Tag):
+                       /* FALLTHROUGH */
+               case (MDOC_Inset):
+                       /* FALLTHROUGH */
+               case (MDOC_Diag):
+                       /* FALLTHROUGH */
+               case (MDOC_Item):
+                       /* FALLTHROUGH */
+               case (MDOC_Ohang):
+                       return(bl->argv[i].arg);
+               default:
+                       break;
+               }
+
+       errx(1, "list type not supported");
+       /* NOTREACHED */
+}
+
+
 static size_t
 arg_offset(const struct mdoc_arg *arg)
 {
 static size_t
 arg_offset(const struct mdoc_arg *arg)
 {
@@ -371,71 +410,45 @@ termp_dq_post(DECL_ARGS)
 
 /* ARGSUSED */
 static int
 
 /* ARGSUSED */
 static int
-termp_it_pre(DECL_ARGS)
+termp_it_pre_block(DECL_ARGS)
 {
 {
-       const struct mdoc_node *n, *it;
+       const struct mdoc_node  *n;
        const struct mdoc_block *bl;
        const struct mdoc_block *bl;
-       char             buf[7], *tp;
-       int              i, type;
-       size_t           width, offset;
 
 
-       switch (node->type) {
-       case (MDOC_BODY):
-               /* FALLTHROUGH */
-       case (MDOC_HEAD):
-               it = node->parent;
-               break;
-       case (MDOC_BLOCK):
-               it = node;
-               break;
-       default:
-               return(1);
-       }
-
-       n = it->parent->parent;
+       n = node->parent->parent;
        bl = &n->data.block;
 
        bl = &n->data.block;
 
-       if (MDOC_BLOCK == node->type) {
-               newln(p);
-               if ( ! arg_hasattr(MDOC_Compact, bl->argc, bl->argv))
-                       if (node->prev || n->prev)
-                               vspace(p);
-               return(1);
-       }
+       newln(p);
+       if ( ! arg_hasattr(MDOC_Compact, bl->argc, bl->argv))
+               if (node->prev || n->prev)
+                       vspace(p);
 
 
-       /* Get our list type. */
+       return(1);
+}
 
 
-       for (type = -1, i = 0; i < (int)bl->argc; i++) 
-               switch (bl->argv[i].arg) {
-               case (MDOC_Bullet):
-                       /* FALLTHROUGH */
-               case (MDOC_Dash):
-                       /* FALLTHROUGH */
-               case (MDOC_Enum):
-                       /* FALLTHROUGH */
-               case (MDOC_Hyphen):
-                       /* FALLTHROUGH */
-               case (MDOC_Tag):
-                       /* FALLTHROUGH */
-               case (MDOC_Inset):
-                       /* FALLTHROUGH */
-               case (MDOC_Diag):
-                       /* FALLTHROUGH */
-               case (MDOC_Ohang):
-                       type = bl->argv[i].arg;
-                       i = (int)bl->argc;
-                       break;
-               default:
-                       errx(1, "list type not supported");
-                       /* NOTREACHED */
-               }
 
 
-       assert(-1 != type);
+/* ARGSUSED */
+static int
+termp_it_pre(DECL_ARGS)
+{
+       const struct mdoc_block *bl;
+       char             buf[7];
+       int              i, type;
+       size_t           width, offset;
 
 
-       /* Save our existing (inherited) margin and offset. */
+       if (MDOC_BLOCK == node->type)
+               return(termp_it_pre_block(p, pair, meta, node));
+
+       /* Get ptr to list block, type, etc. */
+
+       bl = &node->parent->parent->parent->data.block;
+       type = arg_listtype(node->parent->parent->parent);
+
+       /* Save parent attributes. */
 
        pair->offset = p->offset;
        pair->rmargin = p->rmargin;
 
        pair->offset = p->offset;
        pair->rmargin = p->rmargin;
+       pair->flag = p->flags;
 
        /* Get list width and offset. */
 
 
        /* Get list width and offset. */
 
@@ -445,7 +458,11 @@ termp_it_pre(DECL_ARGS)
        i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
        offset = i >= 0 ? arg_offset(&bl->argv[i]) : 0;
 
        i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
        offset = i >= 0 ? arg_offset(&bl->argv[i]) : 0;
 
-       /* Override the width. */
+       /* 
+        * List-type can override the width in the case of fixed-head
+        * values (bullet, dash/hyphen, enum).  Tags need a non-zero
+        * offset.
+        */
 
        switch (type) {
        case (MDOC_Bullet):
 
        switch (type) {
        case (MDOC_Bullet):
@@ -458,25 +475,54 @@ termp_it_pre(DECL_ARGS)
                width = width > 4 ? width : 4;
                break;
        case (MDOC_Tag):
                width = width > 4 ? width : 4;
                break;
        case (MDOC_Tag):
-               if (0 == width)
-                       errx(1, "need non-zero -width");
-               break;
+               if (width)
+                       break;
+               errx(1, "need non-zero %s for list type", 
+                               mdoc_argnames[MDOC_Width]);
        default:
                break;
        }
 
        default:
                break;
        }
 
-       /* Word-wrap control. */
+       /* 
+        * Whitespace control.  Inset bodies need an initial space.
+        */
 
        switch (type) {
        case (MDOC_Diag):
 
        switch (type) {
        case (MDOC_Diag):
-               /* XXX - ignore child macros!? */
-               if (MDOC_HEAD == node->type)
-                       TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_DIAG]);
                /* FALLTHROUGH */
        case (MDOC_Inset):
                /* FALLTHROUGH */
        case (MDOC_Inset):
-               if (MDOC_HEAD == node->type)
+               if (MDOC_BODY == node->type) 
+                       p->flags &= ~TERMP_NOSPACE;
+               else
                        p->flags |= TERMP_NOSPACE;
                break;
                        p->flags |= TERMP_NOSPACE;
                break;
+       default:
+               p->flags |= TERMP_NOSPACE;
+               break;
+       }
+
+       /*
+        * Style flags.  Diagnostic heads need TTYPE_DIAG.
+        */
+
+       switch (type) {
+       case (MDOC_Diag):
+               if (MDOC_HEAD == node->type)
+                       p->flags |= ttypes[TTYPE_DIAG];
+               break;
+       default:
+               break;
+       }
+
+       /*
+        * Pad and break control.  This is the tricker part.  Lists with
+        * set right-margins for the head get TERMP_NOBREAK because, if
+        * they overrun the margin, they wrap to the new margin.
+        * Correspondingly, the body for these types don't left-pad, as
+        * the head will pad out to to the right.
+        */
+
+       switch (type) {
        case (MDOC_Bullet):
                /* FALLTHROUGH */
        case (MDOC_Dash):
        case (MDOC_Bullet):
                /* FALLTHROUGH */
        case (MDOC_Dash):
@@ -486,40 +532,25 @@ termp_it_pre(DECL_ARGS)
        case (MDOC_Hyphen):
                /* FALLTHROUGH */
        case (MDOC_Tag):
        case (MDOC_Hyphen):
                /* FALLTHROUGH */
        case (MDOC_Tag):
-               p->flags |= TERMP_NOSPACE;
                if (MDOC_HEAD == node->type)
                        p->flags |= TERMP_NOBREAK;
                if (MDOC_HEAD == node->type)
                        p->flags |= TERMP_NOBREAK;
-               else if (MDOC_BODY == node->type)
+               else
                        p->flags |= TERMP_NOLPAD;
                break;
                        p->flags |= TERMP_NOLPAD;
                break;
+       case (MDOC_Diag):
+               if (MDOC_HEAD == node->type)
+                       p->flags |= TERMP_NOBREAK;
+               break;
        default:
                break;
        }
 
        /* 
        default:
                break;
        }
 
        /* 
-        * Get a token to use as the HEAD lead-in.  If NULL, we use the
-        * HEAD child. 
+        * Margin control.  Set-head-width lists have their right
+        * margins shortened.  The body for these lists has the offset
+        * necessarily lengthened.  Everybody gets the offset.
         */
 
         */
 
-       tp = NULL;
-
-       if (MDOC_HEAD == node->type) {
-               if (arg_hasattr(MDOC_Bullet, bl->argc, bl->argv))
-                       tp = "\\[bu]";
-               if (arg_hasattr(MDOC_Dash, bl->argc, bl->argv))
-                       tp = "\\-";
-               if (arg_hasattr(MDOC_Enum, bl->argc, bl->argv)) {
-                       (pair->ppair->ppair->count)++;
-                       (void)snprintf(buf, sizeof(buf), "%d.", 
-                                       pair->ppair->ppair->count);
-                       tp = buf;
-               }
-               if (arg_hasattr(MDOC_Hyphen, bl->argc, bl->argv))
-                       tp = "\\-";
-       }
-
-       /* Margin control. */
-
        p->offset += offset;
 
        switch (type) {
        p->offset += offset;
 
        switch (type) {
@@ -534,18 +565,61 @@ termp_it_pre(DECL_ARGS)
        case (MDOC_Tag):
                if (MDOC_HEAD == node->type)
                        p->rmargin = p->offset + width;
        case (MDOC_Tag):
                if (MDOC_HEAD == node->type)
                        p->rmargin = p->offset + width;
-               else if (MDOC_BODY == node->type) 
+               else 
                        p->offset += width;
                        p->offset += width;
-               break;
+               /* FALLTHROUGH */
        default:
                break;
        }
 
        default:
                break;
        }
 
-       if (NULL == tp)
-               return(1);
+       /* 
+        * The dash, hyphen, bullet and enum lists all have a special
+        * HEAD character.  Print it now.
+        */
 
 
-       word(p, tp);
-       return(0);
+       if (MDOC_HEAD == node->type)
+               switch (type) {
+               case (MDOC_Bullet):
+                       word(p, "\\[bu]");
+                       break;
+               case (MDOC_Dash):
+                       /* FALLTHROUGH */
+               case (MDOC_Hyphen):
+                       word(p, "\\-");
+                       break;
+               case (MDOC_Enum):
+                       /* TODO: have a wordfmt or something. */
+                       (pair->ppair->ppair->count)++;
+                       (void)snprintf(buf, sizeof(buf), "%d.", 
+                                       pair->ppair->ppair->count);
+                       word(p, buf);
+                       break;
+               default:
+                       break;
+               }
+
+       /* 
+        * If we're not going to process our header children, indicate
+        * so here.
+        */
+
+       if (MDOC_HEAD == node->type) 
+               switch (type) {
+               case (MDOC_Bullet):
+                       /* FALLTHROUGH */
+               case (MDOC_Item):
+                       /* FALLTHROUGH */
+               case (MDOC_Dash):
+                       /* FALLTHROUGH */
+               case (MDOC_Hyphen):
+                       /* FALLTHROUGH */
+               case (MDOC_Enum):
+                       return(0);
+               default:
+                       break;
+       }
+
+       return(1);
 }
 
 
 }
 
 
@@ -553,46 +627,22 @@ termp_it_pre(DECL_ARGS)
 static void
 termp_it_post(DECL_ARGS)
 {
 static void
 termp_it_post(DECL_ARGS)
 {
-       int                type, i;
-       struct mdoc_block *bl;
+       int                type;
 
        if (MDOC_BODY != node->type && MDOC_HEAD != node->type)
                return;
 
 
        if (MDOC_BODY != node->type && MDOC_HEAD != node->type)
                return;
 
-       assert(MDOC_BLOCK == node->parent->parent->parent->type);
-       assert(MDOC_Bl == node->parent->parent->parent->tok);
-       bl = &node->parent->parent->parent->data.block;
-
-       for (type = -1, i = 0; i < (int)bl->argc; i++) 
-               switch (bl->argv[i].arg) {
-               case (MDOC_Bullet):
-                       /* FALLTHROUGH */
-               case (MDOC_Dash):
-                       /* FALLTHROUGH */
-               case (MDOC_Enum):
-                       /* FALLTHROUGH */
-               case (MDOC_Hyphen):
-                       /* FALLTHROUGH */
-               case (MDOC_Tag):
-                       /* FALLTHROUGH */
-               case (MDOC_Diag):
-                       /* FALLTHROUGH */
-               case (MDOC_Inset):
-                       /* FALLTHROUGH */
-               case (MDOC_Ohang):
-                       type = bl->argv[i].arg;
-                       i = (int)bl->argc;
-                       break;
-               default:
-                       errx(1, "list type not supported");
-                       /* NOTREACHED */
-               }
-
+       type = arg_listtype(node->parent->parent->parent);
 
        switch (type) {
        case (MDOC_Diag):
                /* FALLTHROUGH */
 
        switch (type) {
        case (MDOC_Diag):
                /* FALLTHROUGH */
+       case (MDOC_Item):
+               /* FALLTHROUGH */
        case (MDOC_Inset):
        case (MDOC_Inset):
+               if (MDOC_BODY != node->type)
+                       break;
+               flushln(p);
                break;
        default:
                flushln(p);
                break;
        default:
                flushln(p);
@@ -601,17 +651,7 @@ termp_it_post(DECL_ARGS)
 
        p->offset = pair->offset;
        p->rmargin = pair->rmargin;
 
        p->offset = pair->offset;
        p->rmargin = pair->rmargin;
-
-       switch (type) {
-       case (MDOC_Inset):
-               break;
-       default:
-               if (MDOC_HEAD == node->type)
-                       p->flags &= ~TERMP_NOBREAK;
-               else if (MDOC_BODY == node->type)
-                       p->flags &= ~TERMP_NOLPAD;
-               break;
-       }
+       p->flags = pair->flag;
 }
 
 
 }
 
 
diff --git a/term.h b/term.h
index dec245daafc4045b7bba55ecd7092c8e9caeacc1..32f5f5f7e83e08122b402ac0da8aa25769f4a9b4 100644 (file)
--- a/term.h
+++ b/term.h
@@ -1,4 +1,4 @@
-/* $Id: term.h,v 1.16 2009/03/03 22:17:19 kristaps Exp $ */
+/* $Id: term.h,v 1.17 2009/03/04 13:57:35 kristaps Exp $ */
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -93,8 +93,6 @@ struct        termp {
 #define        TERMP_LITERAL    (1 << 5)       /* Literal words. */
 #define        TERMP_IGNDELIM   (1 << 6)       /* Delims like regulars. */
 #define        TERMP_NONOSPACE  (1 << 7)       /* No space (no autounset). */
 #define        TERMP_LITERAL    (1 << 5)       /* Literal words. */
 #define        TERMP_IGNDELIM   (1 << 6)       /* Delims like regulars. */
 #define        TERMP_NONOSPACE  (1 << 7)       /* No space (no autounset). */
-#define        TERMP_NORPAD     (1 << 8)       /* No rightpad. */
-#define        TERMP_NOINSET    (1 << 9)       /* If NOBREAK, no inset. */
        char             *buf;
        struct termsym   *symtab;       /* Special-symbol table. */
        struct termsym   *styletab;     /* Style table. */
        char             *buf;
        struct termsym   *symtab;       /* Special-symbol table. */
        struct termsym   *styletab;     /* Style table. */
index ebd95aee751b02ff149a6592f0d5f0784b99d328..267e324d468816307f823ae07f534602d64add78 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: validate.c,v 1.66 2009/03/02 17:14:46 kristaps Exp $ */
+/* $Id: validate.c,v 1.67 2009/03/04 13:57:35 kristaps Exp $ */
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
 /*
  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -22,6 +22,8 @@
 
 #include "private.h"
 
 
 #include "private.h"
 
+/* FIXME: .Bl -diag can't have non-text children in HEAD. */
+
 /*
  * Pre- and post-validate macros as they're parsed.  Pre-validation
  * occurs when the macro has been detected and its arguments parsed.
 /*
  * Pre- and post-validate macros as they're parsed.  Pre-validation
  * occurs when the macro has been detected and its arguments parsed.