]> git.cameronkatri.com Git - mandoc.git/commitdiff
Do text production for .Bt, .Ex, .Rv, .Ud at the validation stage
authorIngo Schwarze <schwarze@openbsd.org>
Wed, 11 Jan 2017 17:39:53 +0000 (17:39 +0000)
committerIngo Schwarze <schwarze@openbsd.org>
Wed, 11 Jan 2017 17:39:53 +0000 (17:39 +0000)
rather than in the formatters.  Use NODE_NOSRC flag for .Lb and
NODE_NOSRC and NODE_NOPRT for .St.  Results in a more rigorous
syntax tree and in 135 lines less code.

This work was triggered by a question from Abhinav Upadhyay <er dot
abhinav dot upadhyay at gmail dot com> (NetBSD) on discuss@.

mandocdb.c
mdoc_html.c
mdoc_man.c
mdoc_term.c
mdoc_validate.c

index 241bbea0202c6e93d93bc888ee840eef17e8e88c..133e73670c10753330998752b90ea10e52cc277d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mandocdb.c,v 1.236 2017/01/10 23:36:34 schwarze Exp $ */
+/*     $Id: mandocdb.c,v 1.237 2017/01/11 17:39:53 schwarze Exp $ */
 /*
  * Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -239,7 +239,7 @@ static      const struct mdoc_handler mdocs[MDOC_MAX] = {
        { NULL, 0, 0 },  /* Ac */
        { NULL, 0, 0 },  /* Ao */
        { NULL, 0, 0 },  /* Aq */
-       { NULL, TYPE_At, NODE_NOSRC },  /* At */
+       { NULL, TYPE_At, 0 },  /* At */
        { NULL, 0, 0 },  /* Bc */
        { NULL, 0, 0 },  /* Bf */
        { NULL, 0, 0 },  /* Bo */
@@ -290,7 +290,7 @@ static      const struct mdoc_handler mdocs[MDOC_MAX] = {
        { NULL, 0, 0 },  /* Hf */
        { NULL, 0, 0 },  /* Fr */
        { NULL, 0, 0 },  /* Ud */
-       { NULL, TYPE_Lb, 0 },  /* Lb */
+       { NULL, TYPE_Lb, NODE_NOSRC },  /* Lb */
        { NULL, 0, 0 },  /* Lp */
        { NULL, TYPE_Lk, 0 },  /* Lk */
        { NULL, TYPE_Mt, NODE_NOSRC },  /* Mt */
index 20b344fc5a4882a2f08ad06d8d83f013dc24d29b..81b60cb5bf77be5a071811c0a50193557f826b2d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_html.c,v 1.246 2017/01/10 23:36:34 schwarze Exp $ */
+/*     $Id: mdoc_html.c,v 1.247 2017/01/11 17:39:53 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -70,7 +70,6 @@ static        int               mdoc_bf_pre(MDOC_ARGS);
 static void              mdoc_bk_post(MDOC_ARGS);
 static int               mdoc_bk_pre(MDOC_ARGS);
 static int               mdoc_bl_pre(MDOC_ARGS);
-static int               mdoc_bt_pre(MDOC_ARGS);
 static int               mdoc_cd_pre(MDOC_ARGS);
 static int               mdoc_d1_pre(MDOC_ARGS);
 static int               mdoc_dv_pre(MDOC_ARGS);
@@ -106,7 +105,6 @@ static      int               mdoc_pp_pre(MDOC_ARGS);
 static void              mdoc_quote_post(MDOC_ARGS);
 static int               mdoc_quote_pre(MDOC_ARGS);
 static int               mdoc_rs_pre(MDOC_ARGS);
-static int               mdoc_rv_pre(MDOC_ARGS);
 static int               mdoc_sh_pre(MDOC_ARGS);
 static int               mdoc_skip_pre(MDOC_ARGS);
 static int               mdoc_sm_pre(MDOC_ARGS);
@@ -114,7 +112,6 @@ static      int               mdoc_sp_pre(MDOC_ARGS);
 static int               mdoc_ss_pre(MDOC_ARGS);
 static int               mdoc_sx_pre(MDOC_ARGS);
 static int               mdoc_sy_pre(MDOC_ARGS);
-static int               mdoc_ud_pre(MDOC_ARGS);
 static int               mdoc_va_pre(MDOC_ARGS);
 static int               mdoc_vt_pre(MDOC_ARGS);
 static int               mdoc_xr_pre(MDOC_ARGS);
@@ -157,7 +154,7 @@ static      const struct htmlmdoc mdocs[MDOC_MAX] = {
        {mdoc_quote_pre, mdoc_quote_post}, /* Op */
        {mdoc_ft_pre, NULL}, /* Ot */
        {mdoc_pa_pre, NULL}, /* Pa */
-       {mdoc_rv_pre, NULL}, /* Rv */
+       {mdoc_ex_pre, NULL}, /* Rv */
        {NULL, NULL}, /* St */
        {mdoc_va_pre, NULL}, /* Va */
        {mdoc_vt_pre, NULL}, /* Vt */
@@ -223,10 +220,10 @@ static    const struct htmlmdoc mdocs[MDOC_MAX] = {
        {NULL, NULL}, /* Oc */
        {mdoc_bk_pre, mdoc_bk_post}, /* Bk */
        {NULL, NULL}, /* Ek */
-       {mdoc_bt_pre, NULL}, /* Bt */
+       {NULL, NULL}, /* Bt */
        {NULL, NULL}, /* Hf */
        {mdoc_em_pre, NULL}, /* Fr */
-       {mdoc_ud_pre, NULL}, /* Ud */
+       {NULL, NULL}, /* Ud */
        {mdoc_lb_pre, NULL}, /* Lb */
        {mdoc_pp_pre, NULL}, /* Lp */
        {mdoc_lk_pre, NULL}, /* Lk */
@@ -921,43 +918,9 @@ mdoc_bl_pre(MDOC_ARGS)
 static int
 mdoc_ex_pre(MDOC_ARGS)
 {
-       struct htmlpair   tag;
-       struct tag       *t;
-       struct roff_node *nch;
-
        if (n->prev)
                print_otag(h, TAG_BR, 0, NULL);
-
-       PAIR_CLASS_INIT(&tag, "utility");
-
-       print_text(h, "The");
-
-       for (nch = n->child; nch != NULL; nch = nch->next) {
-               assert(nch->type == ROFFT_TEXT);
-
-               t = print_otag(h, TAG_B, 1, &tag);
-               print_text(h, nch->string);
-               print_tagq(h, t);
-
-               if (nch->next == NULL)
-                       continue;
-
-               if (nch->prev != NULL || nch->next->next != NULL) {
-                       h->flags |= HTML_NOSPACE;
-                       print_text(h, ",");
-               }
-
-               if (nch->next->next == NULL)
-                       print_text(h, "and");
-       }
-
-       if (n->child != NULL && n->child->next != NULL)
-               print_text(h, "utilities exit\\~0");
-       else
-               print_text(h, "utility exits\\~0");
-
-       print_text(h, "on success, and\\~>0 if an error occurs.");
-       return 0;
+       return 1;
 }
 
 static int
@@ -1634,61 +1597,6 @@ mdoc_ic_pre(MDOC_ARGS)
        return 1;
 }
 
-static int
-mdoc_rv_pre(MDOC_ARGS)
-{
-       struct htmlpair  tag;
-       struct tag      *t;
-       struct roff_node *nch;
-
-       if (n->prev)
-               print_otag(h, TAG_BR, 0, NULL);
-
-       PAIR_CLASS_INIT(&tag, "fname");
-
-       if (n->child != NULL) {
-               print_text(h, "The");
-
-               for (nch = n->child; nch != NULL; nch = nch->next) {
-                       t = print_otag(h, TAG_B, 1, &tag);
-                       print_text(h, nch->string);
-                       print_tagq(h, t);
-
-                       h->flags |= HTML_NOSPACE;
-                       print_text(h, "()");
-
-                       if (nch->next == NULL)
-                               continue;
-
-                       if (nch->prev != NULL || nch->next->next != NULL) {
-                               h->flags |= HTML_NOSPACE;
-                               print_text(h, ",");
-                       }
-                       if (nch->next->next == NULL)
-                               print_text(h, "and");
-               }
-
-               if (n->child != NULL && n->child->next != NULL)
-                       print_text(h, "functions return");
-               else
-                       print_text(h, "function returns");
-
-               print_text(h, "the value\\~0 if successful;");
-       } else
-               print_text(h, "Upon successful completion,"
-                    " the value\\~0 is returned;");
-
-       print_text(h, "otherwise the value\\~\\-1 is returned"
-          " and the global variable");
-
-       PAIR_CLASS_INIT(&tag, "var");
-       t = print_otag(h, TAG_B, 1, &tag);
-       print_text(h, "errno");
-       print_tagq(h, t);
-       print_text(h, "is set to indicate the error.");
-       return 0;
-}
-
 static int
 mdoc_va_pre(MDOC_ARGS)
 {
@@ -1815,22 +1723,6 @@ mdoc_sy_pre(MDOC_ARGS)
        return 1;
 }
 
-static int
-mdoc_bt_pre(MDOC_ARGS)
-{
-
-       print_text(h, "is currently in beta test.");
-       return 0;
-}
-
-static int
-mdoc_ud_pre(MDOC_ARGS)
-{
-
-       print_text(h, "currently under development.");
-       return 0;
-}
-
 static int
 mdoc_lb_pre(MDOC_ARGS)
 {
index 594ade1f02004169d2efece917ef1ca377f59bbb..2c19e15fb8baa1c9c27c05c0fcb193025d1e59d9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_man.c,v 1.100 2017/01/10 23:36:34 schwarze Exp $ */
+/*     $Id: mdoc_man.c,v 1.101 2017/01/11 17:39:53 schwarze Exp $ */
 /*
  * Copyright (c) 2011-2017 Ingo Schwarze <schwarze@openbsd.org>
  *
@@ -102,14 +102,12 @@ static    int       pre_no(DECL_ARGS);
 static int       pre_ns(DECL_ARGS);
 static int       pre_pp(DECL_ARGS);
 static int       pre_rs(DECL_ARGS);
-static int       pre_rv(DECL_ARGS);
 static int       pre_sm(DECL_ARGS);
 static int       pre_sp(DECL_ARGS);
 static int       pre_sect(DECL_ARGS);
 static int       pre_sy(DECL_ARGS);
 static void      pre_syn(const struct roff_node *);
 static int       pre_vt(DECL_ARGS);
-static int       pre_ux(DECL_ARGS);
 static int       pre_xr(DECL_ARGS);
 static void      print_word(const char *);
 static void      print_line(const char *, int);
@@ -157,7 +155,7 @@ static      const struct manact manacts[MDOC_MAX + 1] = {
        { cond_body, pre_enc, post_enc, "[", "]" }, /* Op */
        { NULL, pre_ft, post_font, NULL, NULL }, /* Ot */
        { NULL, pre_em, post_font, NULL, NULL }, /* Pa */
-       { NULL, pre_rv, NULL, NULL, NULL }, /* Rv */
+       { NULL, pre_ex, NULL, NULL, NULL }, /* Rv */
        { NULL, NULL, NULL, NULL, NULL }, /* St */
        { NULL, pre_em, post_font, NULL, NULL }, /* Va */
        { NULL, pre_vt, post_vt, NULL, NULL }, /* Vt */
@@ -223,10 +221,10 @@ static    const struct manact manacts[MDOC_MAX + 1] = {
        { NULL, NULL, NULL, NULL, NULL }, /* Oc */
        { NULL, pre_bk, post_bk, NULL, NULL }, /* Bk */
        { NULL, NULL, NULL, NULL, NULL }, /* Ek */
-       { NULL, pre_ux, NULL, "is currently in beta test.", NULL }, /* Bt */
+       { NULL, NULL, NULL, NULL, NULL }, /* Bt */
        { NULL, NULL, NULL, NULL, NULL }, /* Hf */
        { NULL, pre_em, post_font, NULL, NULL }, /* Fr */
-       { NULL, pre_ux, NULL, "currently under development.", NULL }, /* Ud */
+       { NULL, NULL, NULL, NULL, NULL }, /* Ud */
        { NULL, NULL, post_lb, NULL, NULL }, /* Lb */
        { NULL, pre_pp, NULL, NULL, NULL }, /* Lp */
        { NULL, pre_lk, NULL, NULL, NULL }, /* Lk */
@@ -600,10 +598,14 @@ print_node(DECL_ARGS)
                        printf("\\&");
                        outflags &= ~MMAN_spc;
                }
-               if (outflags & MMAN_Sm && ! (n->flags & NODE_DELIMC))
+               if (n->flags & NODE_DELIMC)
+                       outflags &= ~(MMAN_spc | MMAN_spc_force);
+               else if (outflags & MMAN_Sm)
                        outflags |= MMAN_spc_force;
                print_word(n->string);
-               if (outflags & MMAN_Sm && ! (n->flags & NODE_DELIMO))
+               if (n->flags & NODE_DELIMO)
+                       outflags &= ~(MMAN_spc | MMAN_spc_force);
+               else if (outflags & MMAN_Sm)
                        outflags |= MMAN_spc;
        } else {
                /*
@@ -684,36 +686,8 @@ post_enc(DECL_ARGS)
 static int
 pre_ex(DECL_ARGS)
 {
-       struct roff_node *nch;
-
        outflags |= MMAN_br | MMAN_nl;
-
-       print_word("The");
-
-       for (nch = n->child; nch != NULL; nch = nch->next) {
-               font_push('B');
-               print_word(nch->string);
-               font_pop();
-
-               if (nch->next == NULL)
-                       continue;
-
-               if (nch->prev != NULL || nch->next->next != NULL) {
-                       outflags &= ~MMAN_spc;
-                       print_word(",");
-               }
-               if (nch->next->next == NULL)
-                       print_word("and");
-       }
-
-       if (n->child != NULL && n->child->next != NULL)
-               print_word("utilities exit\\~0");
-       else
-               print_word("utility exits\\~0");
-
-       print_word("on success, and\\~>0 if an error occurs.");
-       outflags |= MMAN_nl;
-       return 0;
+       return 1;
 }
 
 static void
@@ -1624,57 +1598,6 @@ pre_rs(DECL_ARGS)
        return 1;
 }
 
-static int
-pre_rv(DECL_ARGS)
-{
-       struct roff_node *nch;
-
-       outflags |= MMAN_br | MMAN_nl;
-
-       if (n->child != NULL) {
-               print_word("The");
-
-               for (nch = n->child; nch != NULL; nch = nch->next) {
-                       font_push('B');
-                       print_word(nch->string);
-                       font_pop();
-
-                       outflags &= ~MMAN_spc;
-                       print_word("()");
-
-                       if (nch->next == NULL)
-                               continue;
-
-                       if (nch->prev != NULL || nch->next->next != NULL) {
-                               outflags &= ~MMAN_spc;
-                               print_word(",");
-                       }
-                       if (nch->next->next == NULL)
-                               print_word("and");
-               }
-
-               if (n->child != NULL && n->child->next != NULL)
-                       print_word("functions return");
-               else
-                       print_word("function returns");
-
-               print_word("the value\\~0 if successful;");
-       } else
-               print_word("Upon successful completion, "
-                   "the value\\~0 is returned;");
-
-       print_word("otherwise the value\\~\\-1 is returned"
-           " and the global variable");
-
-       font_push('I');
-       print_word("errno");
-       font_pop();
-
-       print_word("is set to indicate the error.");
-       outflags |= MMAN_nl;
-       return 0;
-}
-
 static int
 pre_skip(DECL_ARGS)
 {
@@ -1771,16 +1694,3 @@ pre_xr(DECL_ARGS)
        print_word(")");
        return 0;
 }
-
-static int
-pre_ux(DECL_ARGS)
-{
-
-       print_word(manacts[n->tok].prefix);
-       if (NULL == n->child)
-               return 0;
-       outflags &= ~MMAN_spc;
-       print_word("\\ ");
-       outflags &= ~MMAN_spc;
-       return 1;
-}
index 9540b3269fc57064724631a45a6a5ad29fe2c906..dad54c8c44f973b5a4434c9f8c3bc01bf82a7c0b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_term.c,v 1.340 2017/01/10 23:36:34 schwarze Exp $ */
+/*     $Id: mdoc_term.c,v 1.341 2017/01/11 17:39:53 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -91,7 +91,6 @@ static        int       termp_bf_pre(DECL_ARGS);
 static int       termp_bk_pre(DECL_ARGS);
 static int       termp_bl_pre(DECL_ARGS);
 static int       termp_bold_pre(DECL_ARGS);
-static int       termp_bt_pre(DECL_ARGS);
 static int       termp_cd_pre(DECL_ARGS);
 static int       termp_d1_pre(DECL_ARGS);
 static int       termp_eo_pre(DECL_ARGS);
@@ -114,7 +113,6 @@ static      int       termp_nm_pre(DECL_ARGS);
 static int       termp_ns_pre(DECL_ARGS);
 static int       termp_quote_pre(DECL_ARGS);
 static int       termp_rs_pre(DECL_ARGS);
-static int       termp_rv_pre(DECL_ARGS);
 static int       termp_sh_pre(DECL_ARGS);
 static int       termp_skip_pre(DECL_ARGS);
 static int       termp_sm_pre(DECL_ARGS);
@@ -123,7 +121,6 @@ static      int       termp_ss_pre(DECL_ARGS);
 static int       termp_sy_pre(DECL_ARGS);
 static int       termp_tag_pre(DECL_ARGS);
 static int       termp_under_pre(DECL_ARGS);
-static int       termp_ud_pre(DECL_ARGS);
 static int       termp_vt_pre(DECL_ARGS);
 static int       termp_xr_pre(DECL_ARGS);
 static int       termp_xx_pre(DECL_ARGS);
@@ -165,7 +162,7 @@ static      const struct termact termacts[MDOC_MAX] = {
        { termp_quote_pre, termp_quote_post }, /* Op */
        { termp_ft_pre, NULL }, /* Ot */
        { termp_under_pre, NULL }, /* Pa */
-       { termp_rv_pre, NULL }, /* Rv */
+       { termp_ex_pre, NULL }, /* Rv */
        { NULL, NULL }, /* St */
        { termp_under_pre, NULL }, /* Va */
        { termp_vt_pre, NULL }, /* Vt */
@@ -231,10 +228,10 @@ static    const struct termact termacts[MDOC_MAX] = {
        { NULL, NULL }, /* Oc */
        { termp_bk_pre, termp_bk_post }, /* Bk */
        { NULL, NULL }, /* Ek */
-       { termp_bt_pre, NULL }, /* Bt */
+       { NULL, NULL }, /* Bt */
        { NULL, NULL }, /* Hf */
        { termp_under_pre, NULL }, /* Fr */
-       { termp_ud_pre, NULL }, /* Ud */
+       { NULL, NULL }, /* Ud */
        { NULL, termp_lb_post }, /* Lb */
        { termp_sp_pre, NULL }, /* Lp */
        { termp_lk_pre, NULL }, /* Lk */
@@ -1112,92 +1109,11 @@ termp_rs_pre(DECL_ARGS)
        return 1;
 }
 
-static int
-termp_rv_pre(DECL_ARGS)
-{
-       struct roff_node *nch;
-
-       term_newln(p);
-
-       if (n->child != NULL) {
-               term_word(p, "The");
-
-               for (nch = n->child; nch != NULL; nch = nch->next) {
-                       term_fontpush(p, TERMFONT_BOLD);
-                       term_word(p, nch->string);
-                       term_fontpop(p);
-
-                       p->flags |= TERMP_NOSPACE;
-                       term_word(p, "()");
-
-                       if (nch->next == NULL)
-                               continue;
-
-                       if (nch->prev != NULL || nch->next->next != NULL) {
-                               p->flags |= TERMP_NOSPACE;
-                               term_word(p, ",");
-                       }
-                       if (nch->next->next == NULL)
-                               term_word(p, "and");
-               }
-
-               if (n->child != NULL && n->child->next != NULL)
-                       term_word(p, "functions return");
-               else
-                       term_word(p, "function returns");
-
-               term_word(p, "the value\\~0 if successful;");
-       } else
-               term_word(p, "Upon successful completion,"
-                   " the value\\~0 is returned;");
-
-       term_word(p, "otherwise the value\\~\\-1 is returned"
-           " and the global variable");
-
-       term_fontpush(p, TERMFONT_UNDER);
-       term_word(p, "errno");
-       term_fontpop(p);
-
-       term_word(p, "is set to indicate the error.");
-       p->flags |= TERMP_SENTENCE;
-
-       return 0;
-}
-
 static int
 termp_ex_pre(DECL_ARGS)
 {
-       struct roff_node *nch;
-
        term_newln(p);
-       term_word(p, "The");
-
-       for (nch = n->child; nch != NULL; nch = nch->next) {
-               term_fontpush(p, TERMFONT_BOLD);
-               term_word(p, nch->string);
-               term_fontpop(p);
-
-               if (nch->next == NULL)
-                       continue;
-
-               if (nch->prev != NULL || nch->next->next != NULL) {
-                       p->flags |= TERMP_NOSPACE;
-                       term_word(p, ",");
-               }
-
-               if (nch->next->next == NULL)
-                       term_word(p, "and");
-       }
-
-       if (n->child != NULL && n->child->next != NULL)
-               term_word(p, "utilities exit\\~0");
-       else
-               term_word(p, "utility exits\\~0");
-
-       term_word(p, "on success, and\\~>0 if an error occurs.");
-
-       p->flags |= TERMP_SENTENCE;
-       return 0;
+       return 1;
 }
 
 static int
@@ -1398,15 +1314,6 @@ termp_sh_post(DECL_ARGS)
        }
 }
 
-static int
-termp_bt_pre(DECL_ARGS)
-{
-
-       term_word(p, "is currently in beta test.");
-       p->flags |= TERMP_SENTENCE;
-       return 0;
-}
-
 static void
 termp_lb_post(DECL_ARGS)
 {
@@ -1415,15 +1322,6 @@ termp_lb_post(DECL_ARGS)
                term_newln(p);
 }
 
-static int
-termp_ud_pre(DECL_ARGS)
-{
-
-       term_word(p, "currently under development.");
-       p->flags |= TERMP_SENTENCE;
-       return 0;
-}
-
 static int
 termp_d1_pre(DECL_ARGS)
 {
index b54c27c239079ee27ef402c0149d6ffd0eff6c7f..043145ae1ccc9f5fe082f108dca4ae9863cf2568 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_validate.c,v 1.316 2017/01/10 23:36:34 schwarze Exp $ */
+/*     $Id: mdoc_validate.c,v 1.317 2017/01/11 17:39:53 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -51,6 +51,7 @@ enum  check_ineq {
 
 typedef        void    (*v_post)(POST_ARGS);
 
+static int      build_list(struct roff_man *, int);
 static void     check_text(struct roff_man *, int, int, char *);
 static void     check_argv(struct roff_man *,
                        struct roff_node *, struct mdoc_argv *);
@@ -95,6 +96,7 @@ static        void     post_par(POST_ARGS);
 static void     post_prevpar(POST_ARGS);
 static void     post_root(POST_ARGS);
 static void     post_rs(POST_ARGS);
+static void     post_rv(POST_ARGS);
 static void     post_sh(POST_ARGS);
 static void     post_sh_head(POST_ARGS);
 static void     post_sh_name(POST_ARGS);
@@ -143,7 +145,7 @@ static      v_post mdoc_valids[MDOC_MAX] = {
        NULL,           /* Op */
        post_obsolete,  /* Ot */
        post_defaults,  /* Pa */
-       post_std,       /* Rv */
+       post_rv,        /* Rv */
        post_st,        /* St */
        NULL,           /* Va */
        NULL,           /* Vt */
@@ -621,6 +623,10 @@ post_bd(POST_ARGS)
        }
 }
 
+/*
+ * Stand-alone line macros.
+ */
+
 static void
 post_an_norm(POST_ARGS)
 {
@@ -648,6 +654,158 @@ post_an_norm(POST_ARGS)
                abort();
 }
 
+static void
+post_eoln(POST_ARGS)
+{
+       struct roff_node        *n;
+
+       n = mdoc->last;
+       if (n->child != NULL)
+               mandoc_vmsg(MANDOCERR_ARG_SKIP, mdoc->parse,
+                   n->line, n->pos, "%s %s",
+                   mdoc_macronames[n->tok], n->child->string);
+
+       while (n->child != NULL)
+               roff_node_delete(mdoc, n->child);
+
+       roff_word_alloc(mdoc, n->line, n->pos, n->tok == MDOC_Bt ?
+           "is currently in beta test." : "currently under development.");
+       mdoc->last->flags |= NODE_EOS | NODE_NOSRC;
+       mdoc->last = n;
+}
+
+static int
+build_list(struct roff_man *mdoc, int tok)
+{
+       struct roff_node        *n;
+       int                      ic;
+
+       n = mdoc->last->next;
+       for (ic = 1;; ic++) {
+               roff_elem_alloc(mdoc, n->line, n->pos, tok);
+               mdoc->last->flags |= NODE_NOSRC;
+               mdoc_node_relink(mdoc, n);
+               n = mdoc->last = mdoc->last->parent;
+               mdoc->next = ROFF_NEXT_SIBLING;
+               if (n->next == NULL)
+                       return ic;
+               if (ic > 1 || n->next->next != NULL) {
+                       roff_word_alloc(mdoc, n->line, n->pos, ",");
+                       mdoc->last->flags |= NODE_DELIMC | NODE_NOSRC;
+               }
+               n = mdoc->last->next;
+               if (n->next == NULL) {
+                       roff_word_alloc(mdoc, n->line, n->pos, "and");
+                       mdoc->last->flags |= NODE_NOSRC;
+               }
+       }
+}
+
+static void
+post_ex(POST_ARGS)
+{
+       struct roff_node        *n;
+       int                      ic;
+
+       post_std(mdoc);
+
+       n = mdoc->last;
+       mdoc->next = ROFF_NEXT_CHILD;
+       roff_word_alloc(mdoc, n->line, n->pos, "The");
+       mdoc->last->flags |= NODE_NOSRC;
+
+       if (mdoc->last->next != NULL)
+               ic = build_list(mdoc, MDOC_Nm);
+       else if (mdoc->meta.name != NULL) {
+               roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Nm);
+               mdoc->last->flags |= NODE_NOSRC;
+               roff_word_alloc(mdoc, n->line, n->pos, mdoc->meta.name);
+               mdoc->last->flags |= NODE_NOSRC;
+               mdoc->last = mdoc->last->parent;
+               mdoc->next = ROFF_NEXT_SIBLING;
+               ic = 1;
+       } else {
+               mandoc_msg(MANDOCERR_EX_NONAME, mdoc->parse,
+                   n->line, n->pos, "Ex");
+               ic = 0;
+       }
+
+       roff_word_alloc(mdoc, n->line, n->pos,
+           ic > 1 ? "utilities exit\\~0" : "utility exits\\~0");
+       mdoc->last->flags |= NODE_NOSRC;
+       roff_word_alloc(mdoc, n->line, n->pos,
+           "on success, and\\~>0 if an error occurs.");
+       mdoc->last->flags |= NODE_EOS | NODE_NOSRC;
+       mdoc->last = n;
+}
+
+static void
+post_lb(POST_ARGS)
+{
+       struct roff_node        *n;
+       const char              *p;
+
+       n = mdoc->last;
+       assert(n->child->type == ROFFT_TEXT);
+       mdoc->next = ROFF_NEXT_CHILD;
+
+       if ((p = mdoc_a2lib(n->child->string)) != NULL) {
+               n->child->flags |= NODE_NOPRT;
+               roff_word_alloc(mdoc, n->line, n->pos, p);
+               mdoc->last->flags = NODE_NOSRC;
+               mdoc->last = n;
+               return;
+       }
+
+       roff_word_alloc(mdoc, n->line, n->pos, "library");
+       mdoc->last->flags = NODE_NOSRC;
+       roff_word_alloc(mdoc, n->line, n->pos, "\\(Lq");
+       mdoc->last->flags = NODE_DELIMO | NODE_NOSRC;
+       mdoc->last = mdoc->last->next;
+       roff_word_alloc(mdoc, n->line, n->pos, "\\(Rq");
+       mdoc->last->flags = NODE_DELIMC | NODE_NOSRC;
+       mdoc->last = n;
+}
+
+static void
+post_rv(POST_ARGS)
+{
+       struct roff_node        *n;
+       int                      ic;
+
+       post_std(mdoc);
+
+       n = mdoc->last;
+       mdoc->next = ROFF_NEXT_CHILD;
+       if (n->child != NULL) {
+               roff_word_alloc(mdoc, n->line, n->pos, "The");
+               mdoc->last->flags |= NODE_NOSRC;
+               ic = build_list(mdoc, MDOC_Fn);
+               roff_word_alloc(mdoc, n->line, n->pos,
+                   ic > 1 ? "functions return" : "function returns");
+               mdoc->last->flags |= NODE_NOSRC;
+               roff_word_alloc(mdoc, n->line, n->pos,
+                   "the value\\~0 if successful;");
+       } else
+               roff_word_alloc(mdoc, n->line, n->pos, "Upon successful "
+                   "completion, the value\\~0 is returned;");
+       mdoc->last->flags |= NODE_NOSRC;
+
+       roff_word_alloc(mdoc, n->line, n->pos, "otherwise "
+           "the value\\~\\-1 is returned and the global variable");
+       mdoc->last->flags |= NODE_NOSRC;
+       roff_elem_alloc(mdoc, n->line, n->pos, MDOC_Va);
+       mdoc->last->flags |= NODE_NOSRC;
+       roff_word_alloc(mdoc, n->line, n->pos, "errno");
+       mdoc->last->flags |= NODE_NOSRC;
+       mdoc->last = mdoc->last->parent;
+       mdoc->next = ROFF_NEXT_SIBLING;
+       roff_word_alloc(mdoc, n->line, n->pos,
+           "is set to indicate the error.");
+       mdoc->last->flags |= NODE_EOS | NODE_NOSRC;
+       mdoc->last = n;
+}
+
 static void
 post_std(POST_ARGS)
 {
@@ -662,6 +820,30 @@ post_std(POST_ARGS)
            n->line, n->pos, mdoc_macronames[n->tok]);
 }
 
+static void
+post_st(POST_ARGS)
+{
+       struct roff_node         *n, *nch;
+       const char               *p;
+
+       n = mdoc->last;
+       nch = n->child;
+       assert(nch->type == ROFFT_TEXT);
+
+       if ((p = mdoc_a2st(nch->string)) == NULL) {
+               mandoc_vmsg(MANDOCERR_ST_BAD, mdoc->parse,
+                   nch->line, nch->pos, "St %s", nch->string);
+               roff_node_delete(mdoc, n);
+               return;
+       }
+
+       nch->flags |= NODE_NOPRT;
+       mdoc->next = ROFF_NEXT_CHILD;
+       roff_word_alloc(mdoc, nch->line, nch->pos, p);
+       mdoc->last->flags |= NODE_NOSRC;
+       mdoc->last= n;
+}
+
 static void
 post_obsolete(POST_ARGS)
 {
@@ -673,6 +855,10 @@ post_obsolete(POST_ARGS)
                    n->line, n->pos, mdoc_macronames[n->tok]);
 }
 
+/*
+ * Block macros.
+ */
+
 static void
 post_bf(POST_ARGS)
 {
@@ -738,39 +924,6 @@ post_bf(POST_ARGS)
                    "Bf %s", np->child->string);
 }
 
-static void
-post_lb(POST_ARGS)
-{
-       struct roff_node        *n;
-       const char              *stdlibname;
-       char                    *libname;
-
-       n = mdoc->last->child;
-       assert(n->type == ROFFT_TEXT);
-
-       if (NULL == (stdlibname = mdoc_a2lib(n->string)))
-               mandoc_asprintf(&libname,
-                   "library \\(Lq%s\\(Rq", n->string);
-       else
-               libname = mandoc_strdup(stdlibname);
-
-       free(n->string);
-       n->string = libname;
-}
-
-static void
-post_eoln(POST_ARGS)
-{
-       const struct roff_node *n;
-
-       n = mdoc->last;
-       if (n->child != NULL)
-               mandoc_vmsg(MANDOCERR_ARG_SKIP,
-                   mdoc->parse, n->line, n->pos,
-                   "%s %s", mdoc_macronames[n->tok],
-                   n->child->string);
-}
-
 static void
 post_fname(POST_ARGS)
 {
@@ -1448,27 +1601,6 @@ post_root(POST_ARGS)
                    n->line, n->pos, mdoc_macronames[n->tok]);
 }
 
-static void
-post_st(POST_ARGS)
-{
-       struct roff_node         *n, *nch;
-       const char               *p;
-
-       n = mdoc->last;
-       nch = n->child;
-
-       assert(nch->type == ROFFT_TEXT);
-
-       if ((p = mdoc_a2st(nch->string)) == NULL) {
-               mandoc_vmsg(MANDOCERR_ST_BAD, mdoc->parse,
-                   nch->line, nch->pos, "St %s", nch->string);
-               roff_node_delete(mdoc, n);
-       } else {
-               free(nch->string);
-               nch->string = mandoc_strdup(p);
-       }
-}
-
 static void
 post_rs(POST_ARGS)
 {
@@ -2203,32 +2335,6 @@ post_os(POST_ARGS)
 #endif /*!OSNAME*/
 }
 
-/*
- * If no argument is provided,
- * fill in the name of the current manual page.
- */
-static void
-post_ex(POST_ARGS)
-{
-       struct roff_node *n;
-
-       post_std(mdoc);
-
-       n = mdoc->last;
-       if (n->child != NULL)
-               return;
-
-       if (mdoc->meta.name == NULL) {
-               mandoc_msg(MANDOCERR_EX_NONAME, mdoc->parse,
-                   n->line, n->pos, "Ex");
-               return;
-       }
-
-       mdoc->next = ROFF_NEXT_CHILD;
-       roff_word_alloc(mdoc, n->line, n->pos, mdoc->meta.name);
-       mdoc->last = n;
-}
-
 enum roff_sec
 mdoc_a2sec(const char *p)
 {