%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
