=================================================================== RCS file: /cvs/docbook2mdoc/parse.c,v retrieving revision 1.36 retrieving revision 1.37 diff -u -p -r1.36 -r1.37 --- docbook2mdoc/parse.c 2019/04/12 07:05:19 1.36 +++ docbook2mdoc/parse.c 2019/04/12 07:53:09 1.37 @@ -1,4 +1,4 @@ -/* $Id: parse.c,v 1.36 2019/04/12 07:05:19 schwarze Exp $ */ +/* $Id: parse.c,v 1.37 2019/04/12 07:53:09 schwarze Exp $ */ /* * Copyright (c) 2014 Kristaps Dzonsons * Copyright (c) 2019 Ingo Schwarze @@ -412,10 +412,10 @@ xml_text(struct parse *p, const char *word, int sz) * Close out the text node and strip trailing whitespace, if one is open. */ static void -pnode_closetext(struct parse *p) +pnode_closetext(struct parse *p, int check_last_word) { struct pnode *n; - char *cp; + char *cp, *last_word; if ((n = p->cur) == NULL || n->node != NODE_TEXT) return; @@ -424,6 +424,32 @@ pnode_closetext(struct parse *p) cp > n->b && isspace((unsigned char)cp[-1]); *--cp = '\0') p->flags |= PFLAG_SPC; + + if (p->flags & PFLAG_SPC || !check_last_word) + return; + + /* + * Find the beginning of the last word + * and delete whitespace before it. + */ + + while (cp > n->b && !isspace((unsigned char)cp[-1])) + cp--; + if (cp == n->b) + return; + + last_word = cp; + while (cp > n->b && isspace((unsigned char)cp[-1])) + *--cp = '\0'; + + /* Move the last word into its own node, for use with .Pf. */ + + if ((n = pnode_alloc(p->cur)) == NULL) + fatal(p); + n->node = NODE_TEXT; + n->spc = 1; + if ((n->b = strdup(last_word)) == NULL) + fatal(p); } static void @@ -443,7 +469,7 @@ xml_entity(struct parse *p, const char *name) return; } - pnode_closetext(p); + pnode_closetext(p, 0); if (p->tree->flags & TREE_CLOSED && p->cur == p->tree->root) warn_msg(p, "entity after end of document: &%s;", name); @@ -509,7 +535,7 @@ xml_elem_start(struct parse *p, const char *name) return; } - pnode_closetext(p); + pnode_closetext(p, 1); for (elem = elements; elem->name != NULL; elem++) if (strcmp(elem->name, name) == 0) @@ -681,7 +707,7 @@ xml_elem_end(struct parse *p, const char *name) } if (p->del == 0) - pnode_closetext(p); + pnode_closetext(p, 0); if (name != NULL) { for (elem = elements; elem->name != NULL; elem++) @@ -1007,7 +1033,7 @@ parse_string(struct parse *p, char *b, size_t rlen, refill); xml_text(p, b + poff, pend - poff); if (b[pend] == '\n') - pnode_closetext(p); + pnode_closetext(p, 0); } } return poff; @@ -1092,7 +1118,7 @@ parse_file(struct parse *p, int fd, const char *fname) /* On the top level, finalize the parse tree. */ if (save_fname == NULL) { - pnode_closetext(p); + pnode_closetext(p, 0); if (p->tree->root == NULL) error_msg(p, "empty document"); else if ((p->tree->flags & TREE_CLOSED) == 0)