%pointer
%s PRETEXT NOTE sTEXT

%{

/*
 * Filter to add vile "attribution" sequences to selected bits of fdl
 * input text.  This treats all of the text area as quoted, except for
 * out-of-bounds text.  Fields are shown as variable.
 */

#include <filters.h>

DefineFilter ("fdl");

#if 1
static char *Comment_attr;

#	if 2
static char *Ident2_attr;

#	else
static char *Keyword_attr;
static char *String_attr;
#	endif
#endif

static int next_state;

%}

%{

static void handle_keyword (char *name);

%}

BLANK		[ \t]*
REMAINDER	[^\r\n]*

KEYWORD		$[[:alpha:]_][[:alnum:]_]*

%%

<INITIAL,sTEXT>^{BLANK}	{ ECHO; }

<INITIAL,sTEXT>{KEYWORD}	{ handle_keyword(yytext); }
<PRETEXT>{REMAINDER}	{ ECHO;
			  if (next_state == sTEXT) {
				BEGIN(sTEXT);
			  } else {
				BEGIN(INITIAL);
			  }
			}

<NOTE>[\n]		{ ECHO; BEGIN(INITIAL); }
<NOTE>{REMAINDER}	{ WriteToken(Comment_attr);
			  BEGIN(INITIAL); }

<sTEXT>[_]+		{ WriteToken(Ident2_attr); }
<sTEXT>[^$_\r\n]+	{ WriteToken(String_attr); }

%%

static void
handle_keyword (char *name)
{
	flt_puts (name, (int) strlen (name), keyword_attr (name));
	next_state = INITIAL;
	if (!strcmp (name, "$rem")) {
		BEGIN (NOTE);
	} else if (!strcmp (name, "$text")) {
		BEGIN (PRETEXT);
		next_state = sTEXT;
	} else {
		BEGIN (INITIAL);
	}
}

static void
init_filter (int before GCC_UNUSED)
{
	(void) before;
}

static void
do_filter (FILE * inputs)
{
#		if 1
	InitLEX (inputs);
#else

	Comment_attr = class_attr (NAME_COMMENT);
	Ident2_attr = class_attr (NAME_IDENT2);
	Keyword_attr = class_attr (NAME_KEYWORD);
	String_attr = class_attr (NAME_LITERAL);
#	endif

	next_state = INITIAL;

	BEGIN (INITIAL);
	RunLEX ();
}

#if NO_LEAKS
static void
free_filter (void)
{
	USE_LEXFREE;
}
#endif
