]> git.cameronkatri.com Git - mandoc.git/blobdiff - mdoc_term.c
Fixed `Bd' prior vertical space (was ignoring -compact).
[mandoc.git] / mdoc_term.c
index de4b92588f619530d30284e09f8a0bc9cd6b10dd..4c0c8af632c1e5e734d98b431daec8dc31f0d193 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_term.c,v 1.74 2009/09/20 17:48:13 kristaps Exp $ */
+/*     $Id: mdoc_term.c,v 1.85 2009/09/26 17:35:49 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -106,6 +106,7 @@ static      void      termp_sq_post(DECL_ARGS);
 static void      termp_ss_post(DECL_ARGS);
 static void      termp_vt_post(DECL_ARGS);
 
+static int       termp__t_pre(DECL_ARGS);
 static int       termp_an_pre(DECL_ARGS);
 static int       termp_ap_pre(DECL_ARGS);
 static int       termp_aq_pre(DECL_ARGS);
@@ -113,7 +114,6 @@ static      int       termp_bd_pre(DECL_ARGS);
 static int       termp_bf_pre(DECL_ARGS);
 static int       termp_bold_pre(DECL_ARGS);
 static int       termp_bq_pre(DECL_ARGS);
-static int       termp_br_pre(DECL_ARGS);
 static int       termp_brq_pre(DECL_ARGS);
 static int       termp_bt_pre(DECL_ARGS);
 static int       termp_cd_pre(DECL_ARGS);
@@ -133,7 +133,6 @@ static      int       termp_nm_pre(DECL_ARGS);
 static int       termp_ns_pre(DECL_ARGS);
 static int       termp_op_pre(DECL_ARGS);
 static int       termp_pf_pre(DECL_ARGS);
-static int       termp_pp_pre(DECL_ARGS);
 static int       termp_pq_pre(DECL_ARGS);
 static int       termp_qq_pre(DECL_ARGS);
 static int       termp_rs_pre(DECL_ARGS);
@@ -155,7 +154,7 @@ static      const struct termact termacts[MDOC_MAX] = {
        { NULL, NULL }, /* Os */
        { termp_sh_pre, termp_sh_post }, /* Sh */
        { termp_ss_pre, termp_ss_post }, /* Ss */ 
-       { termp_pp_pre, NULL }, /* Pp */ 
+       { termp_sp_pre, NULL }, /* Pp */ 
        { termp_d1_pre, termp_d1_post }, /* D1 */
        { termp_d1_pre, termp_d1_post }, /* Dl */
        { termp_bd_pre, termp_bd_post }, /* Bd */
@@ -191,15 +190,15 @@ static    const struct termact termacts[MDOC_MAX] = {
        { termp_under_pre, termp_vt_post }, /* Vt */
        { termp_xr_pre, NULL }, /* Xr */
        { NULL, termp____post }, /* %A */
-       { NULL, termp____post }, /* %B */
+       { termp_under_pre, termp____post }, /* %B */
        { NULL, termp____post }, /* %D */
-       { NULL, termp____post }, /* %I */
+       { termp_under_pre, termp____post }, /* %I */
        { termp_under_pre, termp____post }, /* %J */
        { NULL, termp____post }, /* %N */
        { NULL, termp____post }, /* %O */
        { NULL, termp____post }, /* %P */
        { NULL, termp____post }, /* %R */
-       { termp_under_pre, termp____post }, /* %T */
+       { termp__t_pre, termp____post }, /* %T */
        { NULL, termp____post }, /* %V */
        { NULL, NULL }, /* Ac */
        { termp_aq_pre, termp_aq_post }, /* Ao */
@@ -220,7 +219,7 @@ static      const struct termact termacts[MDOC_MAX] = {
        { termp_under_pre, NULL }, /* Em */ 
        { NULL, NULL }, /* Eo */
        { termp_xx_pre, NULL }, /* Fx */
-       { termp_bold_pre, NULL }, /* Ms */
+       { termp_bold_pre, NULL }, /* Ms */ /* FIXME: convert to symbol? */
        { NULL, NULL }, /* No */
        { termp_ns_pre, NULL }, /* Ns */
        { termp_xx_pre, NULL }, /* Nx */
@@ -256,18 +255,18 @@ static    const struct termact termacts[MDOC_MAX] = {
        { NULL, NULL }, /* Fr */
        { termp_ud_pre, NULL }, /* Ud */
        { NULL, termp_lb_post }, /* Lb */
-       { termp_pp_pre, NULL }, /* Lp */ 
+       { termp_sp_pre, NULL }, /* Lp */ 
        { termp_lk_pre, NULL }, /* Lk */ 
        { termp_under_pre, NULL }, /* Mt */ 
        { termp_brq_pre, termp_brq_post }, /* Brq */ 
        { termp_brq_pre, termp_brq_post }, /* Bro */ 
        { NULL, NULL }, /* Brc */ 
-       { NULL, NULL }, /* %C */ 
-       { NULL, NULL }, /* Es */ 
-       { NULL, NULL }, /* En */ 
+       { NULL, termp____post }, /* %C */ 
+       { NULL, NULL }, /* Es */ /* TODO */
+       { NULL, NULL }, /* En */ /* TODO */
        { termp_xx_pre, NULL }, /* Dx */ 
-       { NULL, NULL }, /* %Q */ 
-       { termp_br_pre, NULL }, /* br */
+       { NULL, termp____post }, /* %Q */ 
+       { termp_sp_pre, NULL }, /* br */
        { termp_sp_pre, NULL }, /* sp */ 
 };
 
@@ -424,6 +423,7 @@ print_foot(DECL_ARGS)
 }
 
 
+/* FIXME: put in utility library. */
 /* ARGSUSED */
 static void
 print_head(DECL_ARGS)
@@ -639,15 +639,10 @@ fmt_block_vspace(struct termp *p,
        const struct mdoc_node *n;
 
        term_newln(p);
-
-       if (MDOC_Bl == bl->tok && arg_hasattr(MDOC_Compact, bl))
+       if (arg_hasattr(MDOC_Compact, bl))
                return;
-       assert(node);
 
-       /*
-        * Search through our prior nodes.  If we follow a `Ss' or `Sh',
-        * then don't vspace.
-        */
+       /* Do not vspace directly after Ss/Sh. */
 
        for (n = node; n; n = n->parent) {
                if (MDOC_BLOCK != n->type)
@@ -661,19 +656,14 @@ fmt_block_vspace(struct termp *p,
                break;
        }
 
-       /* 
-        * XXX - not documented: a `-column' does not ever assert vspace
-        * within the list.
-        */
+       /* A `-column' does not assert vspace within the list. */
 
        if (MDOC_Bl == bl->tok && arg_hasattr(MDOC_Column, bl))
                if (node->prev && MDOC_It == node->prev->tok)
                        return;
 
-       /*
-        * XXX - not documented: a `-diag' without a body does not
-        * assert a vspace prior to the next element. 
-        */
+       /* A `-diag' without body does not vspace. */
+
        if (MDOC_Bl == bl->tok && arg_hasattr(MDOC_Diag, bl)) 
                if (node->prev && MDOC_It == node->prev->tok) {
                        assert(node->prev->body);
@@ -763,13 +753,13 @@ termp_it_pre(DECL_ARGS)
                 * last column case, set to stretch to the margin).
                 */
                for (i = 0, n = node->prev; n && 
-                               i < (int)bl->args[vals[2]].argv->sz; 
+                               i < (int)bl->args->argv[vals[2]].sz; 
                                n = n->prev, i++)
                        offset += arg_width 
                                (&bl->args->argv[vals[2]], i);
 
                /* Whether exceeds maximum column. */
-               if (i < (int)bl->args[vals[2]].argv->sz)
+               if (i < (int)bl->args->argv[vals[2]].sz)
                        width = arg_width(&bl->args->argv[vals[2]], i);
                else
                        width = 0;
@@ -1100,13 +1090,12 @@ termp_an_pre(DECL_ARGS)
                return(1);
 
        /*
-        * XXX: this is poorly documented.  If not in the AUTHORS
-        * section, `An -split' will cause newlines to occur before the
-        * author name.  If in the AUTHORS section, by default, the
-        * first `An' invocation is nosplit, then all subsequent ones,
-        * regardless of whether interspersed with other macros/text,
-        * are split.  -split, in this case, will override the condition
-        * of the implied first -nosplit.
+        * If not in the AUTHORS section, `An -split' will cause
+        * newlines to occur before the author name.  If in the AUTHORS
+        * section, by default, the first `An' invocation is nosplit,
+        * then all subsequent ones, regardless of whether interspersed
+        * with other macros/text, are split.  -split, in this case,
+        * will override the condition of the implied first -nosplit.
         */
        
        if (node->sec == SEC_AUTHORS) {
@@ -1160,21 +1149,13 @@ termp_ns_pre(DECL_ARGS)
 }
 
 
-/* ARGSUSED */
-static int
-termp_pp_pre(DECL_ARGS)
-{
-
-       term_vspace(p);
-       return(1);
-}
-
-
 /* ARGSUSED */
 static int
 termp_rs_pre(DECL_ARGS)
 {
 
+       if (SEC_SEE_ALSO != node->sec)
+               return(1);
        if (MDOC_BLOCK == node->type && node->prev)
                term_vspace(p);
        return(1);
@@ -1360,10 +1341,9 @@ termp_fd_post(DECL_ARGS)
 static int
 termp_sh_pre(DECL_ARGS)
 {
-       /* 
-        * XXX: undocumented: using two `Sh' macros in sequence has no
-        * vspace between calls, only a newline.
-        */
+
+       /* No vspace between consecutive `Sh' calls. */
+
        switch (node->type) {
        case (MDOC_BLOCK):
                if (node->prev && MDOC_Sh == node->prev->tok)
@@ -1426,7 +1406,7 @@ termp_bt_pre(DECL_ARGS)
 {
 
        term_word(p, "is currently in beta test.");
-       return(1);
+       return(0);
 }
 
 
@@ -1435,7 +1415,8 @@ static void
 termp_lb_post(DECL_ARGS)
 {
 
-       term_newln(p);
+       if (SEC_LIBRARY == node->sec)
+               term_newln(p);
 }
 
 
@@ -1527,10 +1508,6 @@ termp_fn_pre(DECL_ARGS)
 {
        const struct mdoc_node *n;
 
-       assert(node->child && MDOC_TEXT == node->child->type);
-
-       /* FIXME: can be "type funcname" "type varname"... */
-
        p->bold++;
        term_word(p, node->child->string);
        p->bold--;
@@ -1595,18 +1572,8 @@ termp_fa_pre(DECL_ARGS)
 static int
 termp_bd_pre(DECL_ARGS)
 {
-       int              i, type;
-
-       /*
-        * This is fairly tricky due primarily to crappy documentation.
-        * If -ragged or -filled are specified, the block does nothing
-        * but change the indentation.
-        *
-        * If, on the other hand, -unfilled or -literal are specified,
-        * then the game changes.  Text is printed exactly as entered in
-        * the display: if a macro line, a newline is appended to the
-        * line.  Blank lines are allowed.
-        */
+       int                      i, type;
+       const struct mdoc_node  *nn;
 
        if (MDOC_BLOCK == node->type) {
                fmt_block_vspace(p, node, node);
@@ -1614,11 +1581,10 @@ termp_bd_pre(DECL_ARGS)
        } else if (MDOC_BODY != node->type)
                return(1);
 
-       assert(node->parent->args);
+       nn = node->parent;
 
-       for (type = -1, i = 0; -1 == type && 
-                       i < (int)node->parent->args->argc; i++) {
-               switch (node->parent->args->argv[i].arg) {
+       for (type = -1, i = 0; i < (int)nn->args->argc; i++) {
+               switch (nn->args->argv[i].arg) {
                case (MDOC_Ragged):
                        /* FALLTHROUGH */
                case (MDOC_Filled):
@@ -1626,32 +1592,33 @@ termp_bd_pre(DECL_ARGS)
                case (MDOC_Unfilled):
                        /* FALLTHROUGH */
                case (MDOC_Literal):
-                       type = node->parent->args->argv[i].arg;
+                       type = nn->args->argv[i].arg;
+                       break;
+               case (MDOC_Offset):
+                       p->offset += arg_offset(&nn->args->argv[i]);
                        break;
                default:
                        break;
                }
        }
+
+       /*
+        * If -ragged or -filled are specified, the block does nothing
+        * but change the indentation.  If -unfilled or -literal are
+        * specified, text is printed exactly as entered in the display:
+        * for macro lines, a newline is appended to the line.  Blank
+        * lines are allowed.
+        */
        
        assert(type > -1);
-
-       i = arg_getattr(MDOC_Offset, node->parent);
-       if (-1 != i)
-               p->offset += arg_offset(&node->parent->args->argv[i]);
-
-       switch (type) {
-       case (MDOC_Literal):
-               /* FALLTHROUGH */
-       case (MDOC_Unfilled):
-               break;
-       default:
+       if (MDOC_Literal != type && MDOC_Unfilled != type)
                return(1);
-       }
 
-       for (node = node->child; node; node = node->next) {
-               p->flags |= TERMP_NOSPACE;
-               print_node(p, pair, meta, node);
-               if (node->next)
+       for (nn = node->child; nn; nn = nn->next) {
+               print_node(p, pair, meta, nn);
+               if (NULL == nn->next)
+                       continue;
+               if (nn->prev && nn->prev->line < nn->line)
                        term_flushln(p);
        }
 
@@ -1853,6 +1820,7 @@ termp_in_post(DECL_ARGS)
 {
 
        p->bold++;
+       p->flags |= TERMP_NOSPACE;
        term_word(p, ">");
        p->bold--;
 
@@ -1877,12 +1845,18 @@ termp_sp_pre(DECL_ARGS)
 {
        int              i, len;
 
-       if (NULL == node->child) {
-               term_vspace(p);
-               return(0);
+       switch (node->tok) {
+       case (MDOC_sp):
+               len = node->child ? atoi(node->child->string) : 1;
+               break;
+       case (MDOC_br):
+               len = 0;
+               break;
+       default:
+               len = 1;
+               break;
        }
 
-       len = atoi(node->child->string);
        if (0 == len)
                term_newln(p);
        for (i = 0; i < len; i++)
@@ -1892,16 +1866,6 @@ termp_sp_pre(DECL_ARGS)
 }
 
 
-/* ARGSUSED */
-static int
-termp_br_pre(DECL_ARGS)
-{
-
-       term_newln(p);
-       return(1);
-}
-
-
 /* ARGSUSED */
 static int
 termp_brq_pre(DECL_ARGS)
@@ -2080,6 +2044,14 @@ termp____post(DECL_ARGS)
 {
 
        p->flags |= TERMP_NOSPACE;
+       switch (node->tok) {
+       case (MDOC__T):
+               term_word(p, "\\(rq");
+               p->flags |= TERMP_NOSPACE;
+               break;
+       default:
+               break;
+       }
        term_word(p, node->next ? "," : ".");
 }
 
@@ -2121,3 +2093,14 @@ termp_under_pre(DECL_ARGS)
        p->under++;
        return(1);
 }
+
+
+/* ARGSUSED */
+static int
+termp__t_pre(DECL_ARGS)
+{
+
+       term_word(p, "\\(lq");
+       p->flags |= TERMP_NOSPACE;
+       return(1);
+}