]> git.cameronkatri.com Git - mandoc.git/commitdiff
Accomodate (libman) for next-line macros followed by non-text macros `na', `sp',...
authorKristaps Dzonsons <kristaps@bsd.lv>
Mon, 22 Mar 2010 05:59:32 +0000 (05:59 +0000)
committerKristaps Dzonsons <kristaps@bsd.lv>
Mon, 22 Mar 2010 05:59:32 +0000 (05:59 +0000)
Based on a patch by Ingo Schwarze.

libman.h
man.7
man.c
man_html.c
man_macro.c
man_term.c
man_validate.c

index c0b5cb462f43389c2d3a7673798e1f1d4544c8c2..ad33e44fe4fe020f3788614fa7e0c6f4a857c036 100644 (file)
--- a/libman.h
+++ b/libman.h
@@ -1,4 +1,4 @@
-/*     $Id: libman.h,v 1.23 2009/10/30 05:58:36 kristaps Exp $ */
+/*     $Id: libman.h,v 1.24 2010/03/22 05:59:32 kristaps Exp $ */
 /*
  * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -30,9 +30,10 @@ struct       man {
        int              pflags;
        int              flags;
 #define        MAN_HALT        (1 << 0)
-#define        MAN_ELINE       (1 << 1)        /* Next-line element scope. */
-#define        MAN_BLINE       (1 << 2)        /* Next-line block scope. */
-#define        MAN_LITERAL     (1 << 3)        /* Literal input. */
+#define        MAN_ELINE       (1 << 1) /* Next-line element scope. */
+#define        MAN_BLINE       (1 << 2) /* Next-line block scope. */
+#define        MAN_ILINE       (1 << 3) /* Ignored in next-line scope. */
+#define        MAN_LITERAL     (1 << 4) /* Literal input. */
        enum man_next    next;
        struct man_node *last;
        struct man_node *first;
@@ -70,6 +71,7 @@ struct        man_macro {
 #define        MAN_SCOPED       (1 << 0)
 #define        MAN_EXPLICIT     (1 << 1)       /* See blk_imp(). */
 #define        MAN_FSCOPED      (1 << 2)       /* See blk_imp(). */
+#define        MAN_NSCOPED      (1 << 3)       /* See in_line_eoln(). */
 };
 
 extern const struct man_macro *const man_macros;
diff --git a/man.7 b/man.7
index 7d1ee602315638b7e1f1413d11b71e378a089614..173adb629dfea0813b6d763f05ef0cd76bb0d3b4 100644 (file)
--- a/man.7
+++ b/man.7
@@ -1,4 +1,4 @@
-.\"    $Id: man.7,v 1.55 2010/01/07 19:10:09 kristaps Exp $
+.\"    $Id: man.7,v 1.56 2010/03/22 05:59:32 kristaps Exp $
 .\"
 .\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
 .\"
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: January 7 2010 $
+.Dd $Mdocdate: March 22 2010 $
 .Dt MAN 7
 .Os
 .
@@ -423,8 +423,8 @@ subsequent lines until closed by another block macro.
 .Ss Line Macros
 Line macros are generally scoped to the current line, with the body
 consisting of zero or more arguments.  If a macro is scoped to the next
-line and the line arguments are empty, the next line is used instead,
-else the general syntax is used.  Thus:
+line and the line arguments are empty, the next line, which must be
+text, is used instead.  Thus:
 .Bd -literal -offset indent
 \&.I
 foo
@@ -433,9 +433,15 @@ foo
 .Pp
 is equivalent to
 .Sq \&.I foo .
-If next-line macros are invoked consecutively, only the last is used; in
-other words, if a next-line macro is preceded by a block macro, it is
-ignored.
+If next-line macros are invoked consecutively, only the last is used.
+If a next-line macro is followed by a non-next-line macro, an error is
+raised (unless in the case of
+.Sx \&br ,
+.Sx \&sp ,
+or
+.Sx \&na ) .
+.Pp
+The syntax is as follows:
 .Bd -literal -offset indent
 \&.YO \(lBbody...\(rB
 \(lBbody...\(rB
@@ -488,8 +494,10 @@ macros should not be used.  They're included for compatibility.
 .Ss Block Macros
 Block macros are comprised of a head and body.  Like for in-line macros,
 the head is scoped to the current line and, in one circumstance, the
-next line; the body is scoped to subsequent lines and is closed out by a
-subsequent block macro invocation.
+next line (the next-line stipulations for line macros apply here as
+well).
+.Pp
+The syntax is as follows:
 .Bd -literal -offset indent
 \&.YO \(lBhead...\(rB
 \(lBhead...\(rB
diff --git a/man.c b/man.c
index c3e5a8940ccf560e9e403df6673578e2cb292b46..d823a5d14d4593dd4578bc685aaca8a91d672b40 100644 (file)
--- a/man.c
+++ b/man.c
@@ -1,4 +1,4 @@
-/*     $Id: man.c,v 1.49 2010/01/07 10:24:43 kristaps Exp $ */
+/*     $Id: man.c,v 1.50 2010/03/22 05:59:32 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -534,15 +534,29 @@ man_pmacro(struct man *m, int ln, char *buf)
                if ( ! man_pwarn(m, ln, i - 1, WTSPACE))
                        goto err;
 
-       /* Remove prior ELINE macro, if applicable. */
+       /* 
+        * Remove prior ELINE macro, as a macro is clobbering it by
+        * being invoked without prior text.  Note that NSCOPED macros
+        * do not close out ELINE macros, as they print no text.
+        */
 
-       if (m->flags & MAN_ELINE) {
+       if (m->flags & MAN_ELINE && 
+                       ! (MAN_NSCOPED & man_macros[c].flags)) {
                n = m->last;
                assert(NULL == n->child);
                assert(0 == n->nchild);
                if ( ! man_nwarn(m, n, WLNSCOPE))
                        return(0);
 
+               /* FIXME: when called as in:
+                *
+                * .B
+                * .br
+                * .B
+                * .br
+                * hello
+                */
+
                if (n->prev) {
                        assert(n != n->parent->child);
                        assert(n == n->prev->next);
@@ -568,8 +582,25 @@ man_pmacro(struct man *m, int ln, char *buf)
                goto err;
 
 out:
-       if ( ! (MAN_BLINE & fl))
+       /* 
+        * We weren't in a block-line scope when entering the
+        * above-parsed macro, so return.
+        */
+
+       if ( ! (MAN_BLINE & fl)) {
+               m->flags &= ~MAN_ILINE; 
                return(1);
+       }
+
+       /*
+        * If we're in a block scope, then allow this macro to slip by
+        * without closing scope around it.
+        */
+
+       if (MAN_ILINE & m->flags) {
+               m->flags &= ~MAN_ILINE;
+               return(1);
+       }
 
        /* 
         * If we've opened a new next-line element scope, then return
index a9db1dfac055a9af399a4df169e3f95315b9ab71..b5e69343d4179128502fd5d8fda33b6930f6bcce 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: man_html.c,v 1.26 2010/01/29 14:39:38 kristaps Exp $ */
+/*     $Id: man_html.c,v 1.27 2010/03/22 05:59:32 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -574,8 +574,12 @@ man_IP_pre(MAN_ARGS)
                        width = a2width(nn, &su);
                }
 
-       if (MAN_TP == n->tok && NULL != nn)
+       if (MAN_TP == n->tok && NULL != nn) {
+               while (nn && MAN_TEXT != nn->type)
+                       nn = nn->next;
+               /* FIXME: sync with pre_TP(), man_term.c */
                width = a2width(nn, &su);
+       }
 
        if (MAN_BLOCK == n->type) {
                bufcat_su(h, "margin-left", &su);
@@ -605,6 +609,8 @@ man_IP_pre(MAN_ARGS)
        if ( ! width)
                return(1);
 
+       /* FIXME: sync with pre_TP(), man_term.c */
+
        if (MAN_IP == n->tok)
                for (nn = n->child; nn->next; nn = nn->next)
                        print_man_node(m, nn, h);
index 845cc29b5cfe6d929fec06d00c9c043ba75ff2e9..0781bbda425ff82e4ddeae408b5ec342f39c2b4f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: man_macro.c,v 1.30 2010/01/01 17:14:28 kristaps Exp $ */
+/*     $Id: man_macro.c,v 1.31 2010/03/22 05:59:32 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -40,7 +40,7 @@ static        int              rew_block(int, enum man_type,
                                const struct man_node *);
 
 const  struct man_macro __man_macros[MAN_MAX] = {
-       { in_line_eoln, 0 }, /* br */
+       { in_line_eoln, MAN_NSCOPED }, /* br */
        { in_line_eoln, 0 }, /* TH */
        { blk_imp, MAN_SCOPED }, /* SH */
        { blk_imp, MAN_SCOPED }, /* SS */
@@ -61,9 +61,9 @@ const struct man_macro __man_macros[MAN_MAX] = {
        { in_line_eoln, MAN_SCOPED }, /* I */
        { in_line_eoln, 0 }, /* IR */
        { in_line_eoln, 0 }, /* RI */
-       { in_line_eoln, 0 }, /* na */
+       { in_line_eoln, MAN_NSCOPED }, /* na */
        { in_line_eoln, 0 }, /* i */
-       { in_line_eoln, 0 }, /* sp */
+       { in_line_eoln, MAN_NSCOPED }, /* sp */
        { in_line_eoln, 0 }, /* nf */
        { in_line_eoln, 0 }, /* fi */
        { in_line_eoln, 0 }, /* r */
@@ -320,14 +320,29 @@ in_line_eoln(MACRO_PROT_ARGS)
                        return(0);
        }
 
+       /*
+        * If no arguments are specified and this is MAN_SCOPED (i.e.,
+        * next-line scoped), then set our mode to indicate that we're
+        * waiting for terms to load into our context.
+        */
+
        if (n == m->last && MAN_SCOPED & man_macros[tok].flags) {
+               assert( ! (MAN_NSCOPED & man_macros[tok].flags));
                m->flags |= MAN_ELINE;
                return(1);
        } 
 
+       /* Set ignorable context, if applicable. */
+
+       if (MAN_NSCOPED & man_macros[tok].flags) {
+               assert( ! (MAN_SCOPED & man_macros[tok].flags));
+               m->flags |= MAN_ILINE;
+       }
+       
        /*
-        * Note that when TH is pruned, we'll be back at the root, so
-        * make sure that we don't clobber as its sibling.
+        * Rewind our element scope.  Note that when TH is pruned, we'll
+        * be back at the root, so make sure that we don't clobber as
+        * its sibling.
         */
 
        for ( ; m->last; m->last = m->last->parent) {
index f6df381c3fef89ad5d07c41d91156849bdff0256..0a012d04cd17e13de066e71cfaaa1b085ee328de 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: man_term.c,v 1.55 2010/01/01 17:14:28 kristaps Exp $ */
+/*     $Id: man_term.c,v 1.56 2010/03/22 05:59:32 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -65,6 +65,8 @@ struct        mtermp {
 struct termact {
        int             (*pre)(DECL_ARGS);
        void            (*post)(DECL_ARGS);
+       int               flags;
+#define        MAN_NOTEXT       (1 << 0) /* Never has text children. */
 };
 
 static int               a2width(const struct man_node *);
@@ -105,38 +107,38 @@ static    void              post_SS(DECL_ARGS);
 static void              post_TP(DECL_ARGS);
 
 static const struct termact termacts[MAN_MAX] = {
-       { pre_br, NULL }, /* br */
-       { NULL, NULL }, /* TH */
-       { pre_SH, post_SH }, /* SH */
-       { pre_SS, post_SS }, /* SS */
-       { pre_TP, post_TP }, /* TP */
-       { pre_PP, NULL }, /* LP */
-       { pre_PP, NULL }, /* PP */
-       { pre_PP, NULL }, /* P */
-       { pre_IP, post_IP }, /* IP */
-       { pre_HP, post_HP }, /* HP */ 
-       { NULL, NULL }, /* SM */
-       { pre_B, NULL }, /* SB */
-       { pre_BI, NULL }, /* BI */
-       { pre_BI, NULL }, /* IB */
-       { pre_RB, NULL }, /* BR */
-       { pre_RB, NULL }, /* RB */
-       { NULL, NULL }, /* R */
-       { pre_B, NULL }, /* B */
-       { pre_I, NULL }, /* I */
-       { pre_RI, NULL }, /* IR */
-       { pre_RI, NULL }, /* RI */
-       { NULL, NULL }, /* na */
-       { pre_I, NULL }, /* i */
-       { pre_sp, NULL }, /* sp */
-       { pre_nf, NULL }, /* nf */
-       { pre_fi, NULL }, /* fi */
-       { NULL, NULL }, /* r */
-       { NULL, NULL }, /* RE */
-       { pre_RS, post_RS }, /* RS */
-       { pre_ign, NULL }, /* DT */
-       { pre_ign, NULL }, /* UC */
-       { pre_ign, NULL }, /* PD */
+       { pre_br, NULL, MAN_NOTEXT }, /* br */
+       { NULL, NULL, 0 }, /* TH */
+       { pre_SH, post_SH, 0 }, /* SH */
+       { pre_SS, post_SS, 0 }, /* SS */
+       { pre_TP, post_TP, 0 }, /* TP */
+       { pre_PP, NULL, 0 }, /* LP */
+       { pre_PP, NULL, 0 }, /* PP */
+       { pre_PP, NULL, 0 }, /* P */
+       { pre_IP, post_IP, 0 }, /* IP */
+       { pre_HP, post_HP, 0 }, /* HP */ 
+       { NULL, NULL, 0 }, /* SM */
+       { pre_B, NULL, 0 }, /* SB */
+       { pre_BI, NULL, 0 }, /* BI */
+       { pre_BI, NULL, 0 }, /* IB */
+       { pre_RB, NULL, 0 }, /* BR */
+       { pre_RB, NULL, 0 }, /* RB */
+       { NULL, NULL, 0 }, /* R */
+       { pre_B, NULL, 0 }, /* B */
+       { pre_I, NULL, 0 }, /* I */
+       { pre_RI, NULL, 0 }, /* IR */
+       { pre_RI, NULL, 0 }, /* RI */
+       { NULL, NULL, MAN_NOTEXT }, /* na */
+       { pre_I, NULL, 0 }, /* i */
+       { pre_sp, NULL, MAN_NOTEXT }, /* sp */
+       { pre_nf, NULL, 0 }, /* nf */
+       { pre_fi, NULL, 0 }, /* fi */
+       { NULL, NULL, 0 }, /* r */
+       { NULL, NULL, 0 }, /* RE */
+       { pre_RS, post_RS, 0 }, /* RS */
+       { pre_ign, NULL, 0 }, /* DT */
+       { pre_ign, NULL, 0 }, /* UC */
+       { pre_ign, NULL, 0 }, /* PD */
 };
 
 
@@ -574,10 +576,13 @@ pre_TP(DECL_ARGS)
 
        /* Calculate offset. */
 
-       if (NULL != (nn = n->parent->head->child))
-               if (NULL != nn->next)
+       if (NULL != (nn = n->parent->head->child)) {
+               while (nn && MAN_TEXT != nn->type)
+                       nn = nn->next;
+               if (nn && nn->next)
                        if ((ival = a2width(nn)) >= 0)
                                len = (size_t)ival;
+       }
 
        switch (n->type) {
        case (MAN_HEAD):
@@ -803,7 +808,8 @@ print_man_node(DECL_ARGS)
                }
                break;
        default:
-               term_fontrepl(p, TERMFONT_NONE);
+               if ( ! (MAN_NOTEXT & termacts[n->tok].flags))
+                       term_fontrepl(p, TERMFONT_NONE);
                if (termacts[n->tok].pre)
                        c = (*termacts[n->tok].pre)(p, mt, n, m);
                break;
@@ -815,7 +821,8 @@ print_man_node(DECL_ARGS)
        if (MAN_TEXT != n->type) {
                if (termacts[n->tok].post)
                        (*termacts[n->tok].post)(p, mt, n, m);
-               term_fontrepl(p, TERMFONT_NONE);
+               if ( ! (MAN_NOTEXT & termacts[n->tok].flags))
+                       term_fontrepl(p, TERMFONT_NONE);
        }
 }
 
index 0d4eceec5f171fa6b1e7f28077d567e5b7e0badc..4776445e7dc66a82c207bb018f5bc92f3c9c8f3d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: man_validate.c,v 1.28 2010/01/01 17:14:28 kristaps Exp $ */
+/*     $Id: man_validate.c,v 1.29 2010/03/22 05:59:32 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *
@@ -59,7 +59,7 @@ static        v_check   posts_sp[] = { check_le1, NULL };
 static v_check   pres_bline[] = { check_bline, NULL };
 
 static const struct man_valid man_valids[MAN_MAX] = {
-       { pres_bline, posts_eq0 }, /* br */
+       { NULL, posts_eq0 }, /* br */
        { pres_bline, posts_ge2_le5 }, /* TH */ /* FIXME: make sure capitalised. */
        { pres_bline, posts_sec }, /* SH */
        { pres_bline, posts_sec }, /* SS */
@@ -80,9 +80,9 @@ static        const struct man_valid man_valids[MAN_MAX] = {
        { NULL, NULL }, /* I */
        { NULL, NULL }, /* IR */
        { NULL, NULL }, /* RI */
-       { pres_bline, posts_eq0 }, /* na */
+       { NULL, posts_eq0 }, /* na */
        { NULL, NULL }, /* i */
-       { pres_bline, posts_sp }, /* sp */
+       { NULL, posts_sp }, /* sp */
        { pres_bline, posts_eq0 }, /* nf */
        { pres_bline, posts_eq0 }, /* fi */
        { NULL, NULL }, /* r */