Beispiel #1
0
/*
 * 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);
}
Beispiel #3
0
/* 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);
}
Beispiel #4
0
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);
}