=================================================================== RCS file: /cvs/mandoc/roff.c,v retrieving revision 1.267 retrieving revision 1.270 diff -u -p -r1.267 -r1.270 --- mandoc/roff.c 2015/04/19 14:25:41 1.267 +++ mandoc/roff.c 2015/05/01 16:02:47 1.270 @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.267 2015/04/19 14:25:41 schwarze Exp $ */ +/* $Id: roff.c,v 1.270 2015/05/01 16:02:47 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons * Copyright (c) 2010-2015 Ingo Schwarze @@ -1022,6 +1022,7 @@ roff_node_append(struct roff_man *man, struct roff_nod /* NOTREACHED */ } n->parent->nchild++; + n->parent->last = n; /* * Copy over the normalised-data pointer of our parent. Not @@ -1096,7 +1097,28 @@ roff_word_append(struct roff_man *man, const char *wor man->next = ROFF_NEXT_SIBLING; } +void +roff_elem_alloc(struct roff_man *man, int line, int pos, int tok) +{ + struct roff_node *n; + + n = roff_node_alloc(man, line, pos, ROFFT_ELEM, tok); + roff_node_append(man, n); + man->next = ROFF_NEXT_CHILD; +} + struct roff_node * +roff_block_alloc(struct roff_man *man, int line, int pos, int tok) +{ + struct roff_node *n; + + n = roff_node_alloc(man, line, pos, ROFFT_BLOCK, tok); + roff_node_append(man, n); + man->next = ROFF_NEXT_CHILD; + return(n); +} + +struct roff_node * roff_head_alloc(struct roff_man *man, int line, int pos, int tok) { struct roff_node *n; @@ -1207,6 +1229,52 @@ roff_node_delete(struct roff_man *man, struct roff_nod assert(n->nchild == 0); roff_node_unlink(man, n); roff_node_free(n); +} + +void +deroff(char **dest, const struct roff_node *n) +{ + char *cp; + size_t sz; + + if (n->type != ROFFT_TEXT) { + for (n = n->child; n != NULL; n = n->next) + deroff(dest, n); + return; + } + + /* Skip leading whitespace and escape sequences. */ + + cp = n->string; + while (*cp != '\0') { + if ('\\' == *cp) { + cp++; + mandoc_escape((const char **)&cp, NULL, NULL); + } else if (isspace((unsigned char)*cp)) + cp++; + else + break; + } + + /* Skip trailing whitespace. */ + + for (sz = strlen(cp); sz; sz--) + if ( ! isspace((unsigned char)cp[sz-1])) + break; + + /* Skip empty strings. */ + + if (sz == 0) + return; + + if (*dest == NULL) { + *dest = mandoc_strndup(cp, sz); + return; + } + + mandoc_asprintf(&cp, "%s %*s", *dest, (int)sz, cp); + free(*dest); + *dest = cp; } /* --- main functions of the roff parser ---------------------------------- */