/* * Phrases occur within `Bl -column' entries, separated by `Ta' or tabs. * They're unusual because they're basically free-form text until a * macro is encountered. */ static int phrase(struct mdoc *m, int line, int ppos, char *buf) { int la, pos; enum margserr ac; enum mdoct ntok; char *p; for (pos = ppos; ; ) { la = pos; ac = mdoc_zargs(m, line, &pos, buf, &p); if (ARGS_ERROR == ac) return(0); if (ARGS_EOLN == ac) break; ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p); if (MDOC_MAX == ntok) { if ( ! dword(m, line, la, p, DELIM_MAX)) return(0); continue; } if ( ! mdoc_macro(m, ntok, line, la, &pos, buf)) return(0); return(append_delims(m, line, &pos, buf)); } return(1); }
/* ARGSUSED */ static int phrase_ta(MACRO_PROT_ARGS) { struct mdoc_node *n; int la; enum mdoct ntok; enum margserr ac; char *p; /* Make sure we are in a column list or ignore this macro. */ n = mdoc->last; while (NULL != n && MDOC_Bl != n->tok) n = n->parent; if (NULL == n || LIST_column != n->norm->Bl.type) { mdoc_pmsg(mdoc, line, ppos, MANDOCERR_STRAYTA); return(1); } /* Advance to the next column. */ if ( ! rew_sub(MDOC_BODY, mdoc, MDOC_It, line, ppos)) return(0); if ( ! mdoc_body_alloc(mdoc, line, ppos, MDOC_It)) return(0); for (;;) { la = *pos; ac = mdoc_zargs(mdoc, line, pos, buf, &p); if (ARGS_ERROR == ac) return(0); if (ARGS_EOLN == ac) break; ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p); if (MDOC_MAX == ntok) { if ( ! dword(mdoc, line, la, p, DELIM_MAX, MDOC_JOIN & mdoc_macros[tok].flags)) return(0); continue; } if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf)) return(0); return(append_delims(mdoc, line, pos, buf)); } return(1); }
/* ARGSUSED */ static int phrase_ta(MACRO_PROT_ARGS) { int la; enum mdoct ntok; enum margserr ac; char *p; /* * FIXME: this is overly restrictive: if the `Ta' is unexpected, * it should simply error out with ARGSLOST. */ if ( ! rew_sub(MDOC_BODY, m, MDOC_It, line, ppos)) return(0); if ( ! mdoc_body_alloc(m, line, ppos, MDOC_It)) return(0); for (;;) { la = *pos; ac = mdoc_zargs(m, line, pos, buf, &p); if (ARGS_ERROR == ac) return(0); if (ARGS_EOLN == ac) break; ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p); if (MDOC_MAX == ntok) { if ( ! dword(m, line, la, p, DELIM_MAX)) return(0); continue; } if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) return(0); return(append_delims(m, line, pos, buf)); } return(1); }
static int append_delims(struct mdoc *m, int line, int *pos, char *buf) { int la; enum margserr ac; char *p; if ('\0' == buf[*pos]) return(1); for (;;) { la = *pos; ac = mdoc_zargs(m, line, pos, buf, ARGS_NOWARN, &p); if (ARGS_ERROR == ac) return(0); else if (ARGS_EOLN == ac) break; assert(DELIM_NONE != mdoc_isdelim(p)); if ( ! mdoc_word_alloc(m, line, la, p)) return(0); /* * If we encounter end-of-sentence symbols, then trigger * the double-space. * * XXX: it's easy to allow this to propogate outward to * the last symbol, such that `. )' will cause the * correct double-spacing. However, (1) groff isn't * smart enough to do this and (2) it would require * knowing which symbols break this behaviour, for * example, `. ;' shouldn't propogate the double-space. */ if (mandoc_eos(p, strlen(p))) m->last->flags |= MDOC_EOS; } return(1); }