diff options
author | Kristaps Dzonsons <kristaps@bsd.lv> | 2010-03-22 14:03:03 +0000 |
---|---|---|
committer | Kristaps Dzonsons <kristaps@bsd.lv> | 2010-03-22 14:03:03 +0000 |
commit | 58e63ca37d1f123e661e096529eb22e418ed5542 (patch) | |
tree | 13a8051a813351883fd089a84e04890a431e867c | |
parent | 32cbe85d8ce6eee87446621fa65138ae97b24bb8 (diff) | |
download | mandoc-58e63ca37d1f123e661e096529eb22e418ed5542.tar.gz |
Clarify -man -T[x]html handling of `br' within `B'.
Consolidated node unlinking in -man.
Conclude nested next-line scope issues noted by Ingo Schwarze.
-rw-r--r-- | libman.h | 2 | ||||
-rw-r--r-- | man.c | 76 | ||||
-rw-r--r-- | man_action.c | 20 | ||||
-rw-r--r-- | man_html.c | 26 | ||||
-rw-r--r-- | mandoc.1 | 16 |
5 files changed, 89 insertions, 51 deletions
@@ -45,6 +45,7 @@ enum merr { WMSEC, WDATE, WLNSCOPE, + WLNSCOPE2, WTSPACE, WTQUOTE, WNODATA, @@ -94,6 +95,7 @@ int man_body_alloc(struct man *, int, int, int); int man_elem_alloc(struct man *, int, int, int); void man_node_free(struct man_node *); void man_node_freelist(struct man_node *); +void man_node_unlink(struct man *, struct man_node *); void man_hash_init(void); int man_hash_find(const char *); int man_macroend(struct man *); @@ -35,6 +35,7 @@ const char *const __man_merrnames[WERRMAX] = { "invalid manual section", /* WMSEC */ "invalid date format", /* WDATE */ "scope of prior line violated", /* WLNSCOPE */ + "over-zealous prior line scope violation", /* WLNSCOPE2 */ "trailing whitespace", /* WTSPACE */ "unterminated quoted parameter", /* WTQUOTE */ "document has no body", /* WNODATA */ @@ -535,41 +536,37 @@ man_pmacro(struct man *m, int ln, char *buf) goto err; /* - * 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. + * Remove prior ELINE macro, as it's being clobbering by a new + * macro. Note that NSCOPED macros do not close out ELINE + * macros---they don't print text---so we let those slip by. */ - if (m->flags & MAN_ELINE && - ! (MAN_NSCOPED & man_macros[c].flags)) { + if ( ! (MAN_NSCOPED & man_macros[c].flags) && + m->flags & MAN_ELINE) { + assert(MAN_TEXT != m->last->type); + + /* + * This occurs in the following construction: + * .B + * .br + * .B + * .br + * I hate man macros. + * Flat-out disallow this madness. + */ + if (MAN_NSCOPED & man_macros[m->last->tok].flags) + return(man_perr(m, ln, ppos, WLNSCOPE)); + n = m->last; + + assert(n); 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); - n->prev->next = NULL; - m->last = n->prev; - m->next = MAN_NEXT_SIBLING; - } else { - assert(n == n->parent->child); - n->parent->child = NULL; - m->last = n->parent; - m->next = MAN_NEXT_CHILD; - } - + man_node_unlink(m, n); man_node_free(n); m->flags &= ~MAN_ELINE; } @@ -671,3 +668,28 @@ man_err(struct man *m, int line, int pos, int iserr, enum merr type) return(man_vwarn(m, line, pos, p)); } + + +void +man_node_unlink(struct man *m, struct man_node *n) +{ + + if (n->prev) { + n->prev->next = n->next; + if (m->last == n) { + assert(NULL == n->next); + m->last = n->prev; + m->next = MAN_NEXT_SIBLING; + } + } else { + n->parent->child = n->next; + if (m->last == n) { + assert(NULL == n->next); + m->last = n->parent; + m->next = MAN_NEXT_CHILD; + } + } + + if (n->next) + n->next->prev = n->prev; +} diff --git a/man_action.c b/man_action.c index 2d3000f5..80f93df1 100644 --- a/man_action.c +++ b/man_action.c @@ -178,24 +178,8 @@ post_TH(struct man *m) if (n && (n = n->next)) m->meta.vol = mandoc_strdup(n->string); - /* - * The end document shouldn't have the prologue macros as part - * of the syntax tree (they encompass only meta-data). - */ - - if (m->last->parent->child == m->last) { - m->last->parent->child = NULL; - n = m->last; - m->last = m->last->parent; - m->next = MAN_NEXT_CHILD; - } else { - assert(m->last->prev); - m->last->prev->next = NULL; - n = m->last; - m->last = m->last->prev; - m->next = MAN_NEXT_SIBLING; - } - + n = m->last; + man_node_unlink(m, n); man_node_freelist(n); return(1); } @@ -181,6 +181,12 @@ print_man_node(MAN_ARGS) bufinit(h); + /* + * FIXME: embedded elements within next-line scopes (e.g., `br' + * within an empty `B') will cause formatting to be forgotten + * due to scope closing out. + */ + switch (n->type) { case (MAN_ROOT): child = man_root_pre(m, n, h); @@ -567,6 +573,8 @@ man_IP_pre(MAN_ARGS) SCALE_HS_INIT(&su, INDENT); width = 0; + /* Width is the last token. */ + if (MAN_IP == n->tok && NULL != nn) if (NULL != (nn = nn->next)) { for ( ; nn->next; nn = nn->next) @@ -574,11 +582,14 @@ man_IP_pre(MAN_ARGS) width = a2width(nn, &su); } + /* Width is the first token. */ + if (MAN_TP == n->tok && NULL != nn) { + /* Skip past non-text children. */ while (nn && MAN_TEXT != nn->type) nn = nn->next; - /* FIXME: sync with pre_TP(), man_term.c */ - width = a2width(nn, &su); + if (nn) + width = a2width(nn, &su); } if (MAN_BLOCK == n->type) { @@ -604,12 +615,19 @@ man_IP_pre(MAN_ARGS) PAIR_STYLE_INIT(&tag, h); print_otag(h, TAG_DIV, 1, &tag); - /* With a length string, manually omit the last child. */ + /* + * Without a length string, we can print all of our children. + */ if ( ! width) return(1); - /* FIXME: sync with pre_TP(), man_term.c */ + /* + * When a length has been specified, we need to carefully print + * our child context: IP gets all children printed but the last + * (the width), while TP gets all children printed but the first + * (the width). + */ if (MAN_IP == n->tok) for (nn = n->child; nn->next; nn = nn->next) @@ -502,8 +502,8 @@ and .Fl T Ns Ar xhtml CSS2 styling used for .Fl m Ns Ar doc -input lists does not render properly in brain-dead browsers, such as -Internet Explorer 6 and earlier. +input lists does not render properly in older browsers, such as Internet +Explorer 6 and earlier. .Pp In .Fl T Ns Ar html @@ -525,3 +525,15 @@ font size escape documented in .Xr mdoc 7 and .Xr man 7 . +.Pp +Nesting elements within next-line element scopes of +.Fl m Ar Ns an , +such as +.Sq br +within an empty +.Sq B , +will confuse +.Fl T Ns Ar html +and +.Fl T Ns Ar xhtml +and cause it to forget the formatting. |