]> git.cameronkatri.com Git - mandoc.git/blobdiff - mdoc_term.c
suboptarg is not portable to Linux (fixed).
[mandoc.git] / mdoc_term.c
index ea374b92ec0928ffce99cd383fd49c9dbab8406c..e7329d2a8dd5cdad0ba8d1195e1e56ad391e665e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_term.c,v 1.9 2009/06/11 12:07:49 kristaps Exp $ */
+/*     $Id: mdoc_term.c,v 1.20 2009/07/04 11:07:34 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -86,10 +86,10 @@ struct      termpair {
        struct termpair  *ppair;
        int               type;
 #define        TERMPAIR_FLAG    (1 << 0)
-       int               flag;
-       size_t            offset;
-       size_t            rmargin;
-       int               count;
+       int               flag;         /* Whether being used. */
+       size_t            offset;       /* Left margin. */
+       size_t            rmargin;      /* Right margin. */
+       int               count;        /* Enum count. */
 };
 
 #define        TERMPAIR_SETFLAG(termp, p, fl) \
@@ -183,7 +183,7 @@ struct      termact {
 };
 
 static const struct termact termacts[MDOC_MAX] = {
-       { NULL, NULL }, /* \" */
+       { termp_ap_pre, NULL }, /* Ap */
        { NULL, NULL }, /* Dd */
        { NULL, NULL }, /* Dt */
        { NULL, NULL }, /* Os */
@@ -290,8 +290,7 @@ static const struct termact termacts[MDOC_MAX] = {
        { NULL, NULL }, /* Fr */
        { termp_ud_pre, NULL }, /* Ud */
        { termp_lb_pre, termp_lb_post }, /* Lb */
-       { termp_ap_pre, NULL }, /* Lb */
-       { termp_pp_pre, NULL }, /* Pp */ 
+       { termp_pp_pre, NULL }, /* Lp */ 
        { termp_lk_pre, NULL }, /* Lk */ 
        { termp_mt_pre, NULL }, /* Mt */ 
        { termp_brq_pre, termp_brq_post }, /* Brq */ 
@@ -336,7 +335,10 @@ mdoc_run(struct termp *p, const struct mdoc *m)
         */
 
        print_head(p, mdoc_meta(m));
-       print_body(p, NULL, mdoc_meta(m), mdoc_node(m));
+       assert(mdoc_node(m));
+       assert(MDOC_ROOT == mdoc_node(m)->type);
+       if (mdoc_node(m)->child)
+               print_body(p, NULL, mdoc_meta(m), mdoc_node(m)->child);
        print_foot(p, mdoc_meta(m));
        return(1);
 }
@@ -415,11 +417,7 @@ print_foot(struct termp *p, const struct mdoc_meta *meta)
 
        tm = localtime(&meta->date);
 
-#ifdef __OpenBSD__
-       if (NULL == strftime(buf, p->rmargin, "%B %d, %Y", tm))
-#else
        if (0 == strftime(buf, p->rmargin, "%B %d, %Y", tm))
-#endif
                err(1, "strftime");
 
        (void)strlcpy(os, meta->os, p->rmargin);
@@ -535,9 +533,9 @@ arg_width(const struct mdoc_argv *arg, int pos)
        assert(pos < (int)arg->sz && pos >= 0);
        assert(arg->value[pos]);
        if (0 == strcmp(arg->value[pos], "indent"))
-               return(INDENT);
+               return(INDENT + 3);
        if (0 == strcmp(arg->value[pos], "indent-two"))
-               return(INDENT * 2);
+               return(INDENT * 2 + 2);
 
        if (0 == (len = (int)strlen(arg->value[pos])))
                return(0);
@@ -547,13 +545,14 @@ arg_width(const struct mdoc_argv *arg, int pos)
                        break;
 
        if (i == len - 1) {
-               if ('n' == arg->value[pos][len - 1]) {
+               if ('n' == arg->value[pos][len - 1] ||
+                               'm' == arg->value[pos][len - 1]) {
                        v = (size_t)atoi(arg->value[pos]);
-                       return(v);
+                       return(v + 2);
                }
 
        }
-       return(strlen(arg->value[pos]) + 1);
+       return(strlen(arg->value[pos]) + 2);
 }
 
 
@@ -592,6 +591,8 @@ arg_listtype(const struct mdoc_node *n)
                        break;
                }
 
+       /* FIXME: mandated by parser. */
+
        errx(1, "list type not supported");
        /* NOTREACHED */
 }
@@ -602,10 +603,15 @@ arg_offset(const struct mdoc_argv *arg)
 {
 
        assert(*arg->value);
+       if (0 == strcmp(*arg->value, "left"))
+               return(0);
        if (0 == strcmp(*arg->value, "indent"))
-               return(INDENT);
+               return(INDENT + 1);
        if (0 == strcmp(*arg->value, "indent-two"))
-               return(INDENT * 2);
+               return((INDENT + 1) * 2);
+
+       /* FIXME: needs to support field-widths (10n, etc.). */
+
        return(strlen(*arg->value));
 }
 
@@ -709,7 +715,7 @@ termp_it_pre(DECL_ARGS)
 {
        const struct mdoc_node *bl, *n;
        char                    buf[7];
-       int                     i, type, keys[3], vals[3];
+       int                     i, type, keys[3], vals[3], sv;
        size_t                  width, offset;
 
        if (MDOC_BLOCK == node->type)
@@ -755,7 +761,7 @@ termp_it_pre(DECL_ARGS)
                if (vals[0] >= 0) 
                        width = arg_width(&bl->args->argv[vals[0]], 0);
                if (vals[1] >= 0) 
-                       offset = arg_offset(&bl->args->argv[vals[1]]);
+                       offset += arg_offset(&bl->args->argv[vals[1]]);
                break;
        }
 
@@ -770,12 +776,14 @@ termp_it_pre(DECL_ARGS)
                /* FALLTHROUGH */
        case (MDOC_Dash):
                /* FALLTHROUGH */
-       case (MDOC_Enum):
-               /* FALLTHROUGH */
        case (MDOC_Hyphen):
                if (width < 4)
                        width = 4;
                break;
+       case (MDOC_Enum):
+               if (width < 5)
+                       width = 5;
+               break;
        case (MDOC_Tag):
                if (0 == width)
                        width = 10;
@@ -785,11 +793,13 @@ termp_it_pre(DECL_ARGS)
        }
 
        /* 
-        * Whitespace control.  Inset bodies need an initial space.
+        * Whitespace control.  Inset bodies need an initial space,
+        * while diagonal bodies need two.
         */
 
        switch (type) {
        case (MDOC_Diag):
+               term_word(p, "\\ ");
                /* FALLTHROUGH */
        case (MDOC_Inset):
                if (MDOC_BODY == node->type) 
@@ -893,17 +903,20 @@ termp_it_pre(DECL_ARGS)
 
        /* 
         * The dash, hyphen, bullet and enum lists all have a special
-        * HEAD character.  Print it now.
+        * HEAD character (temporarily bold, in some cases).  
         */
 
+       sv = p->flags;
        if (MDOC_HEAD == node->type)
                switch (type) {
                case (MDOC_Bullet):
+                       p->flags |= TERMP_BOLD;
                        term_word(p, "\\[bu]");
                        break;
                case (MDOC_Dash):
                        /* FALLTHROUGH */
                case (MDOC_Hyphen):
+                       p->flags |= TERMP_BOLD;
                        term_word(p, "\\-");
                        break;
                case (MDOC_Enum):
@@ -916,6 +929,8 @@ termp_it_pre(DECL_ARGS)
                        break;
                }
 
+       p->flags = sv; /* Restore saved flags. */
+
        /* 
         * If we're not going to process our children, indicate so here.
         */
@@ -1067,6 +1082,8 @@ termp_rv_pre(DECL_ARGS)
 {
        int              i;
 
+       /* FIXME: mandated by parser. */
+
        if (-1 == (i = arg_getattr(MDOC_Std, node)))
                errx(1, "expected -std argument");
        if (1 != node->args->argv[i].sz)
@@ -1100,6 +1117,8 @@ termp_ex_pre(DECL_ARGS)
 {
        int              i;
 
+       /* FIXME: mandated by parser? */
+
        if (-1 == (i = arg_getattr(MDOC_Std, node)))
                errx(1, "expected -std argument");
        if (1 != node->args->argv[i].sz)
@@ -1153,8 +1172,9 @@ termp_xr_pre(DECL_ARGS)
 {
        const struct mdoc_node *n;
 
-       if (NULL == (n = node->child))
-               errx(1, "expected text line argument");
+       assert(node->child && MDOC_TEXT == node->child->type);
+       n = node->child;
+
        term_word(p, n->string);
        if (NULL == (n = n->next)) 
                return(0);
@@ -1288,9 +1308,9 @@ termp_lb_pre(DECL_ARGS)
 {
        const char      *lb;
 
-       if (NULL == node->child)
-               errx(1, "expected text line argument");
-       if ((lb = mdoc_a2lib(node->child->string))) {
+       assert(node->child && MDOC_TEXT == node->child->type);
+       lb = mdoc_a2lib(node->child->string);
+       if (lb) {
                term_word(p, lb);
                return(0);
        }
@@ -1326,7 +1346,8 @@ termp_d1_pre(DECL_ARGS)
        if (MDOC_BLOCK != node->type)
                return(1);
        term_newln(p);
-       p->offset += (pair->offset = INDENT);
+       pair->offset = INDENT + 1;
+       p->offset += pair->offset;
        return(1);
 }
 
@@ -1397,8 +1418,7 @@ termp_fn_pre(DECL_ARGS)
 {
        const struct mdoc_node *n;
 
-       if (NULL == node->child)
-               errx(1, "expected text line arguments");
+       assert(node->child && MDOC_TEXT == node->child->type);
 
        /* FIXME: can be "type funcname" "type varname"... */
 
@@ -1505,6 +1525,8 @@ termp_bd_pre(DECL_ARGS)
        else if (MDOC_BODY != node->type)
                return(1);
 
+       /* FIXME: display type should be mandated by parser. */
+
        if (NULL == node->parent->args)
                errx(1, "missing display type");
 
@@ -1953,8 +1975,7 @@ termp_fo_pre(DECL_ARGS)
 
        p->flags |= ttypes[TTYPE_FUNC_NAME];
        for (n = node->child; n; n = n->next) {
-               if (MDOC_TEXT != n->type)
-                       errx(1, "expected text line argument");
+               assert(MDOC_TEXT == n->type);
                term_word(p, n->string);
        }
        p->flags &= ~ttypes[TTYPE_FUNC_NAME];
@@ -1998,9 +2019,7 @@ termp_bf_pre(DECL_ARGS)
                return(1);
        } 
 
-       if (MDOC_TEXT != n->type)
-               errx(1, "expected text line arguments");
-
+       assert(MDOC_TEXT == n->type);
        if (0 == strcmp("Em", n->string))
                TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
        else if (0 == strcmp("Sy", n->string))
@@ -2036,9 +2055,7 @@ static int
 termp_sm_pre(DECL_ARGS)
 {
 
-       if (NULL == node->child || MDOC_TEXT != node->child->type)
-               errx(1, "expected boolean line argument");
-
+       assert(node->child && MDOC_TEXT == node->child->type);
        if (0 == strcmp("on", node->child->string)) {
                p->flags &= ~TERMP_NONOSPACE;
                p->flags &= ~TERMP_NOSPACE;
@@ -2109,21 +2126,25 @@ termp_lk_pre(DECL_ARGS)
 {
        const struct mdoc_node *n;
 
-       if (NULL == (n = node->child))
-               errx(1, "expected line argument");
+       assert(node->child);
+       n = node->child;
+
+       if (NULL == n->next) {
+               TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_LINK_ANCHOR]);
+               return(1);
+       }
 
        p->flags |= ttypes[TTYPE_LINK_ANCHOR];
        term_word(p, n->string);
-       p->flags &= ~ttypes[TTYPE_LINK_ANCHOR];
        p->flags |= TERMP_NOSPACE;
        term_word(p, ":");
+       p->flags &= ~ttypes[TTYPE_LINK_ANCHOR];
 
        p->flags |= ttypes[TTYPE_LINK_TEXT];
-       for ( ; n; n = n->next) {
+       for (n = n->next; n; n = n->next) 
                term_word(p, n->string);
-       }
-       p->flags &= ~ttypes[TTYPE_LINK_TEXT];
 
+       p->flags &= ~ttypes[TTYPE_LINK_TEXT];
        return(0);
 }