Consolidated node unlinking in -man.
Conclude nested next-line scope issues noted by Ingo Schwarze.
-/* $Id: libman.h,v 1.24 2010/03/22 05:59:32 kristaps Exp $ */
+/* $Id: libman.h,v 1.25 2010/03/22 14:03:03 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
WTSPACE,
WTQUOTE,
WNODATA,
WTSPACE,
WTQUOTE,
WNODATA,
int man_elem_alloc(struct man *, int, int, int);
void man_node_free(struct man_node *);
void man_node_freelist(struct man_node *);
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 *);
void man_hash_init(void);
int man_hash_find(const char *);
int man_macroend(struct man *);
-/* $Id: man.c,v 1.50 2010/03/22 05:59:32 kristaps Exp $ */
+/* $Id: man.c,v 1.51 2010/03/22 14:03:03 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
"invalid manual section", /* WMSEC */
"invalid date format", /* WDATE */
"scope of prior line violated", /* WLNSCOPE */
"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 */
"trailing whitespace", /* WTSPACE */
"unterminated quoted parameter", /* WTQUOTE */
"document has no body", /* WNODATA */
- * 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));
+
assert(NULL == n->child);
assert(0 == n->nchild);
assert(NULL == n->child);
assert(0 == n->nchild);
if ( ! man_nwarn(m, n, WLNSCOPE))
return(0);
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_free(n);
m->flags &= ~MAN_ELINE;
}
man_node_free(n);
m->flags &= ~MAN_ELINE;
}
return(man_vwarn(m, line, pos, p));
}
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;
+}
-/* $Id: man_action.c,v 1.25 2010/01/01 17:14:27 kristaps Exp $ */
+/* $Id: man_action.c,v 1.26 2010/03/22 14:03:03 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
if (n && (n = n->next))
m->meta.vol = mandoc_strdup(n->string);
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);
}
man_node_freelist(n);
return(1);
}
-/* $Id: man_html.c,v 1.27 2010/03/22 05:59:32 kristaps Exp $ */
+/* $Id: man_html.c,v 1.28 2010/03/22 14:03:03 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
+ /*
+ * 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);
switch (n->type) {
case (MAN_ROOT):
child = man_root_pre(m, n, h);
SCALE_HS_INIT(&su, INDENT);
width = 0;
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)
if (MAN_IP == n->tok && NULL != nn)
if (NULL != (nn = nn->next)) {
for ( ; nn->next; nn = nn->next)
width = a2width(nn, &su);
}
width = a2width(nn, &su);
}
+ /* Width is the first token. */
+
if (MAN_TP == n->tok && NULL != nn) {
if (MAN_TP == n->tok && NULL != nn) {
+ /* Skip past non-text children. */
while (nn && MAN_TEXT != nn->type)
nn = nn->next;
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) {
}
if (MAN_BLOCK == n->type) {
PAIR_STYLE_INIT(&tag, h);
print_otag(h, TAG_DIV, 1, &tag);
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.
+ */
- /* 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)
if (MAN_IP == n->tok)
for (nn = n->child; nn->next; nn = nn->next)
-.\" $Id: mandoc.1,v 1.50 2010/01/29 14:39:38 kristaps Exp $
+.\" $Id: mandoc.1,v 1.51 2010/03/22 14:03:03 kristaps Exp $
.\"
.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
.\"
.\"
.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
.\"
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.\" 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 29 2010 $
+.Dd $Mdocdate: March 22 2010 $
.Fl T Ns Ar xhtml
CSS2 styling used for
.Fl m Ns Ar doc
.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.
.Xr mdoc 7
and
.Xr man 7 .
.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.