=================================================================== RCS file: /cvs/mandoc/mdoc_macro.c,v retrieving revision 1.60 retrieving revision 1.65 diff -u -p -r1.60 -r1.65 --- mandoc/mdoc_macro.c 2010/05/13 06:22:11 1.60 +++ mandoc/mdoc_macro.c 2010/05/15 04:47:38 1.65 @@ -1,4 +1,4 @@ -/* $Id: mdoc_macro.c,v 1.60 2010/05/13 06:22:11 kristaps Exp $ */ +/* $Id: mdoc_macro.c,v 1.65 2010/05/15 04:47:38 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -26,6 +26,7 @@ #include #include "libmdoc.h" +#include "libmandoc.h" enum rew { REWIND_REWIND, @@ -48,7 +49,7 @@ static int append_delims(struct mdoc *, static enum mdoct lookup(enum mdoct, const char *); static enum mdoct lookup_raw(const char *); static int phrase(struct mdoc *, int, int, - char *, enum margserr, int); + char *, enum margserr); static enum mdoct rew_alt(enum mdoct); static int rew_dobreak(enum mdoct, const struct mdoc_node *); @@ -888,7 +889,7 @@ in_line(MACRO_PROT_ARGS) static int blk_full(MACRO_PROT_ARGS) { - int la, pcnt; + int la, nl; struct mdoc_arg *arg; struct mdoc_node *head; /* save of head macro */ struct mdoc_node *body; /* save of body macro */ @@ -900,6 +901,8 @@ blk_full(MACRO_PROT_ARGS) enum margverr av; char *p; + nl = MDOC_NEWLINE & m->flags; + /* Close out prior implicit scope. */ if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) { @@ -959,7 +962,7 @@ blk_full(MACRO_PROT_ARGS) ac = ARGS_ERROR; - for (pcnt = 0; ; ) { + for ( ; ; ) { la = *pos; lac = ac; ac = mdoc_args(m, line, pos, buf, tok, &p); @@ -969,12 +972,18 @@ blk_full(MACRO_PROT_ARGS) if (ARGS_EOLN == ac) break; + if (ARGS_PEND == ac) { + if (ARGS_PPHRASE == lac) + ac = ARGS_PPHRASE; + else + ac = ARGS_PHRASE; + } + /* Don't emit leading punct. for phrases. */ if (NULL == head && ARGS_PHRASE != ac && ARGS_PPHRASE != ac && - ARGS_PEND != ac && ARGS_QWORD != ac && 1 == mdoc_isdelim(p)) { if ( ! mdoc_word_alloc(m, line, la, p)) @@ -986,29 +995,18 @@ blk_full(MACRO_PROT_ARGS) if (NULL == head || ARGS_PHRASE == ac || - ARGS_PEND == ac || ARGS_PPHRASE == ac) { if ( ! mdoc_head_alloc(m, line, ppos, tok)) return(0); head = m->last; } - if (ARGS_PHRASE == ac || - ARGS_PEND == ac || - ARGS_PPHRASE == ac) { - /* - * Special treatment for the last phrase. A - * prior ARGS_PHRASE gets is handled as a - * regular ARGS_PHRASE, but a prior ARGS_PPHRASE - * has special handling. - */ - if (ARGS_PEND == ac && ARGS_ERROR == lac) - ac = ARGS_PHRASE; - else if (ARGS_PEND == ac && ARGS_PHRASE == lac) - ac = ARGS_PHRASE; - - if ( ! phrase(m, line, la, buf, ac, pcnt++)) + if (ARGS_PHRASE == ac || ARGS_PPHRASE == ac) { + if (ARGS_PPHRASE == ac) + m->flags |= MDOC_PPHRASE; + if ( ! phrase(m, line, la, buf, ac)) return(0); + m->flags &= ~MDOC_PPHRASE; if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) return(0); continue; @@ -1033,7 +1031,7 @@ blk_full(MACRO_PROT_ARGS) head = m->last; } - if (1 == ppos && ! append_delims(m, line, pos, buf)) + if (nl && ! append_delims(m, line, pos, buf)) return(0); /* If we've already opened our body, exit now. */ @@ -1073,7 +1071,7 @@ blk_full(MACRO_PROT_ARGS) static int blk_part_imp(MACRO_PROT_ARGS) { - int la; + int la, nl; enum mdoct ntok; enum margserr ac; char *p; @@ -1081,6 +1079,8 @@ blk_part_imp(MACRO_PROT_ARGS) struct mdoc_node *body; /* saved body context */ struct mdoc_node *n; + nl = MDOC_NEWLINE & m->flags; + /* * A macro that spans to the end of the line. This is generally * (but not necessarily) called as the first macro. The block @@ -1151,11 +1151,32 @@ blk_part_imp(MACRO_PROT_ARGS) body = m->last; } + for (n = body->child; n && n->next; n = n->next) + /* Do nothing. */ ; + /* + * End of sentence spacing: if the last node is a text node and + * has a trailing period, then mark it as being end-of-sentence. + */ + + if (n && MDOC_TEXT == n->type && n->string) + if (mandoc_eos(n->string, strlen(n->string))) + n->flags |= MDOC_EOS; + + /* Up-propogate the end-of-space flag. */ + + if (n && (MDOC_EOS & n->flags)) { + body->flags |= MDOC_EOS; + body->parent->flags |= MDOC_EOS; + } + + /* * If we can't rewind to our body, then our scope has already * been closed by another macro (like `Oc' closing `Op'). This * is ugly behaviour nodding its head to OpenBSD's overwhelming * crufty use of `Op' breakage. + * + * FIXME - this should be ifdef'd OpenBSD? */ for (n = m->last; n; n = n->parent) if (body == n) @@ -1169,7 +1190,7 @@ blk_part_imp(MACRO_PROT_ARGS) /* Standard appending of delimiters. */ - if (1 == ppos && ! append_delims(m, line, pos, buf)) + if (nl && ! append_delims(m, line, pos, buf)) return(0); /* Rewind scope, if applicable. */ @@ -1291,6 +1312,7 @@ blk_part_exp(MACRO_PROT_ARGS) } +/* ARGSUSED */ static int in_line_argn(MACRO_PROT_ARGS) { @@ -1535,25 +1557,18 @@ obsolete(MACRO_PROT_ARGS) * macro is encountered. */ static int -phrase(struct mdoc *m, int line, int ppos, char *buf, - enum margserr ac, int count) +phrase(struct mdoc *m, int line, int ppos, char *buf, enum margserr ac) { int la, pos; enum margserr aac; enum mdoct ntok; char *p; - assert(ARGS_PHRASE == ac || - ARGS_PEND == ac || - ARGS_PPHRASE == ac); + assert(ARGS_PHRASE == ac || ARGS_PPHRASE == ac); - if (count && ARGS_PPHRASE == ac) - return(mdoc_word_alloc(m, line, ppos, &buf[ppos])); - for (pos = ppos; ; ) { la = pos; - /* Note: no calling context! */ aac = mdoc_zargs(m, line, &pos, buf, 0, &p); if (ARGS_ERROR == aac) @@ -1561,8 +1576,7 @@ phrase(struct mdoc *m, int line, int ppos, char *buf, if (ARGS_EOLN == aac) break; - ntok = ARGS_QWORD == aac || ARGS_PEND == ac ? - MDOC_MAX : lookup_raw(p); + ntok = ARGS_QWORD == aac ? MDOC_MAX : lookup_raw(p); if (MDOC_MAX == ntok) { if ( ! mdoc_word_alloc(m, line, la, p))