/* l2a.l -*- C -*-
+-----------------------------------------------------------------------------
| Abstract:
|    Lex filter to detexify texts (handles really LaTeX, and a bit of TeX).
|
| Authorship:
|    Copyright (c) 1988, 1990 Gisle Hannemyr.
|
|    Permission is granted to hack, make and distribute copies of this program
|    as long as this notice and the copyright notices are not removed.
|    If you intend to distribute changed versions of this program, please make
|    an entry in the "history" log (below) and mark the hacked lines with your
|    initials. I maintain the program, and shall appreiciate copies of bug
|    fixes and new versions.
|    Flames, bug reports, comments and improvements to:
|       snail: Gisle Hannemyr, Brageveien 3A, 0452 Oslo, Norway
|       EAN:   C=no;PRMD=uninett;O=nr;S=Hannemyr;G=Gisle (X.400 SA format)
|              [email protected]                      (RFC-822  format)
|       Inet: [email protected]
|       UUCP: ...!mcsun!ifi!gisle
|
| History:
|    1.0  8 oct 90 [gh] Version 1 posted on comp.sources.misc.
|    0.0 27 dec 88 [gh] Started it.
|
| Bugs:
|    * Works for my style of Latex, but will proably barf on other peoples
|      files.
|    * I can't see how \kill can be handled by lex only.
|    * \cite is hacked.  Should be fixed.
|
| Environment:
|    None.
|
| Diagnostics:
|    Prints plain error messages.  Does not return error codes.
+---------------------------------------------------------------------------*/


%{

/*---( start of user written lex prologue )---------------------------------*/


#include <stdio.h>
#include <string.h>

#define VERSION "1.0"
#define MAXEROR  100
#define ENGLISH   0
#define NORWEGIAN 1

void parseerror();
void bibhead();
void ptabular();
void pfigure();
void pcaption();
void phorline();
void pappendix();
void verbatim();
void pfotnote();
void footnote();


/*---( globals )------------------------------------------------------------*/

char About[] = "\
L2A is a filter to remove markup commands from LaTeX manuscripts.\n\n\
Flames, bug reports, comments and improvements to:\n\
  snail: Gisle Hannemyr, Brageveien 3A, 0452 Oslo, Norway\n\
  EAN:   C=no;PRMD=uninett;O=nr;S=Hannemyr;G=Gisle (X.400 SA format)\n\
         [email protected]                      (RFC-822  format)\n\
  Inet:  [email protected]\n\
  UUCP:  ...!mcsun!ifi!gisle\n";

char Usage[] = "   Usage: l2a (options)\n\
  Valid options:\n\
\t-a       -- about l2a\n\
\t-h       -- print this\n\
\t-n       -- norwegian text\n";

int    LineNo;                     /* Line number for debugging              */
int    Enumber;                    /* Number for enumerate                   */
int    Fnumber = 0;                /* Number for footnotes/endnotes          */
FILE   *BFile;                     /* Bibliography file.                     */
FILE   *FNote;                     /* Temp. file for footnotes.              */
int    Language = ENGLISH;         /* language for inserted text             */

/*---( end of user written lex prologue )-----------------------------------*/

%}

%START EN FN IT QU MM
%n 1000
%p 6000
%a 4000
%e 2000

sp [ \t\n]*
an [0-9a-zA-Z]+

%%

^"\\begin{thebibliography".* { bibhead(); }
^"\\end{thebibliography}"    { ; }
^"\\bibitem["{an}"]{"{an}"}" { fputs(yytext,stderr); }
"\\cite{"[^{\n]*"}"   { yytext[0] = '('; yytext[strlen(yytext)] = ')'; printf("@CITE%s@ ",yytext); }
"\\ref{"[^{\n]*"}"    { yytext[0] = '('; yytext[strlen(yytext)] = ')'; printf("@REF%s@ ", yytext); }
^"\\begin{enumerate}" { BEGIN EN; Enumber = 0; }
^"\\end{enumerate}"   { BEGIN 0;  }
^"\\begin{itemize}"   { BEGIN IT; }
^"\\end{itemize}"     { BEGIN 0;  }
^"\\begin{quote}"     { BEGIN QU; }
^"\\end{quote}"       { BEGIN 0;  }
^"\\begin{quotation}" { BEGIN QU; }
^"\\end{quotation}"   { BEGIN 0;  }
<IT>"\\item"          { putchar('*'); }
<EN>"\\item"          { Enumber++; printf("%d)",Enumber); }
"\\item"              { putchar('+'); }
<QU>\n                { ECHO; LineNo++; fputs("   ",stdout); }
<FN>.                 { footnote();  BEGIN 0; }
"$"                   { BEGIN MM; }
<MM>"$"               { BEGIN 0;  }
<MM>"\\langle"        { putchar('<'); }
<MM>"\\rangle"        { putchar('>'); }
<MM>"\\backslash"     { putchar('\\'); }
^"\\begin{tabular".*  { ptabular();   }
^"\\end{tabular}"     { phorline();   }
^"\\begin{figure".*   { pfigure();    }
^"\\end{figure}"      { phorline();   }
^"\\caption{"         { pcaption();   }
"\\footnote"          { Fnumber++; printf("<%d>",Fnumber); BEGIN FN; }
"\\appendix"          { pappendix();  }
"\\verb"              { verbatim();   }
"\\'{e}"{sp}          { putchar('e'); }
\\ae{sp}              { putchar('{'); }
\\o{sp}               { putchar('|'); }
\\aa{sp}              { putchar('}'); }
\\AE{sp}              { putchar('['); }
\\O{sp}               { putchar('\\'); }
\\AA{sp}              { putchar(']'); }
"&"                   { putchar('\t'); }
"\\>"                 { putchar('\t'); }
"~"                   { putchar(' '); }
"\\ "                 { putchar(' '); }
"\\$"                 { putchar('$'); }
"\\&"                 { putchar('&'); }
"\\%"                 { putchar('%'); }
"\\#"                 { putchar('#'); }
"\\_"                 { putchar('_'); }
"\\{"                 { putchar('{'); }
"\\}"                 { putchar('{'); }
"\\\\"{sp}            { putchar('\n'); }
^"\\vspace".*         { putchar('\n'); }
^"\\title"            { putchar('\n'); }
^"\\author"           { putchar('\n'); }
^"\\date".*           { putchar('\n'); }
^"\\maketitle"        { putchar('\n'); }
^"\\part"             { putchar('\n'); }
^"\\chapter"          { putchar('\n'); }
^"\\section"          {;}
^"\\subsection"       {;}
^"\\subsubsection"    {;}
^"\\paragraph"        {;}
^"\\subparagraph"     {;}
^"\\input lcustom"    {;}
^"\\documentstyle".*  {;}
^"\\pagenumbering".*  {;}
^"\\setcounter".*     {;}
^"\\newcommand".*     {;}
^"\\setlength".*      {;}
^"\\hyphenation".*    {;}
^"\\label".*          {;}
^"\\draftfalse"       {;}
^"\\begin{document}"  {;}
^"\\end{document}"    {;}
^"\\begin{sloppypar}" {;}
^"\\end{sloppypar}"   {;}
^"\\begin{tabbing}"   {;}
^"\\end{tabbing}"     {;}
"\\TeX"               { fputs("TeX",   stdout); }
"\\LaTeX"             { fputs("LaTeX", stdout); }
"\\LtoA"              { fputs("L2A",   stdout); }
"\\ldots"             { fputs("...",   stdout); }
"\\tiny"              {;}
"\\scriptsize"        {;}
"\\footnotesize"      {;}
"\\small"             {;}
"\\normalsize"        {;}
"\\large"             {;}
"\\Large"             {;}
"\\LARGE"             {;}
"\\huge"              {;}
"\\Huge"              {;}
"\\rm"{sp}            {;}
"\\em"{sp}            {;}
"\\bf"{sp}            {;}
"\\it"{sp}            {;}
"\\sl"{sp}            {;}
"\\sf"{sp}            {;}
"\\sc"{sp}            {;}
"\\tt"{sp}            {;}
"{"                   {;}
"}"                   {;}
"%".*                 {;}
"\\-"                 {;}
\n                    { ECHO; LineNo++; }
                    { ECHO; }
"\\"[@A-Za-z]+        { parseerror(12,yytext); yytext[0] = '('; printf("@%s)@ ",yytext); }

%%

/*---( routines )-----------------------------------------------------------*/

void parseerror(type,ss)
int  type;
char *ss;
{
  static errcnt = 0;

  fprintf(stderr,"l2a: Error %d -- ",type);
  switch (type) {
     case  1: fputs("Instruction not recognized",stderr); break;
     case  2: fputs("Wrong number of parameters",stderr); break;
     case  3: fputs("Bad parameter received",stderr); break;
     case  5: fputs("Unknown character set",stderr); break;
     case  6: fputs("Position overflow",stderr); break;
     case 10: fputs("Bogus output request",stderr); break;
     case 11: fputs("Unimplemented command",stderr); break; /* No function */
     case 12: fputs("Unrecognized markup command",stderr); break;  /* No grammar  */
     case 13: fputs("Unhandled command",stderr); break;     /* No semantic */
     default: fputs("Unknown error (internal)",stderr); break;
  } /* switch */
  fprintf(stderr,"\n   @ line %3d: \"%s\"\n",LineNo,ss);
  errcnt++;
  if (errcnt > MAXEROR) {
     fputs("   Too many errors -- aborting\n",stderr);
     exit(-1);
  }
} /* parseerror */


void bibhead()
{
   switch (Language) {
      case ENGLISH:   puts("\nReferences:"); break;
      case NORWEGIAN: puts("\nLitteratur:"); break;
   } /* switch */
} /* bibhead */


void ptabular()
{
   switch (Language) {
      case ENGLISH:   puts("\t<<=============== NB! Typeset as table. NB! ================>>"); break;
      case NORWEGIAN: puts("\t<<============== NB! Settes som tabell. NB! ================>>"); break;
   } /* switch */
}


void pfigure()
{
   switch (Language) {
      case ENGLISH:   puts("\t<<=========== NB! Please insert figure here. NB! ===========>>"); break;
      case NORWEGIAN: puts("\t<<=========== NB! Figur skal settes inn her. NB! ===========>>"); break;
   } /* switch */

}


void pcaption()
{
   switch (Language) {
      case ENGLISH:   puts("\t  --------------- Caption for figure or table: -------------"); break;
      case NORWEGIAN: puts("\t  --------------- Undertekst for bilde/tabell: -------------"); break;
   } /* switch */
}


void phorline()
{
   puts("<<==========================================================>>");
}


void pappendix()
{
   switch (Language) {
      case ENGLISH:   puts("\n\nAPPENDIX\n========\n"); break;
      case NORWEGIAN: puts("\n\nAPPENDIX\n========\n"); break;
   } /* switch */
}

void verbatim()
{
  int cc, ts;

  ts = input();
  for (;;) {
     cc = input();
     if (cc == ts) break;
     putchar(cc);
  } /* forever */
} /* verbatim */


void pfotnote()
{
   switch (Language) {
      case ENGLISH:   puts("\n\nENDNOTES\n========\n"); break;
      case NORWEGIAN: puts("\n\nNOTER\n=====\n"); break;
   } /* switch */
}


void footnote()
{
  int cc, be = 1;

  fprintf(FNote,"<%d>: ", Fnumber);
  while (be) {
     cc = input();
     if      (cc == '{') be++;
     else if (cc == '}') be--;
     else putc(cc,FNote);
  }
  putc('\n',FNote);
  putc('\n',FNote);
} /* footnote */


void bibitem()
{
  int cc, be = 1;

  fprintf(FNote,"<%d>: ", Fnumber);
  while (be) {
     cc = input();
     if      (cc == '{') be++;
     else if (cc == '}') be--;
     else putc(cc,FNote);
  }
  putc('\n',FNote);
  putc('\n',FNote);
} /* footnote */

/*---( main )---------------------------------------------------------------*/

main (argc, argv)
int argc;
char **argv;
{

  fprintf(stderr,"l2a, version %s -- Copyright (c) 1988, 1990 Gisle Hannemyr\n\n",VERSION);

  argc--; argv++;           /* skip program name  */
  while (argc && (**argv == '-')) {
     (*argv)++;             /* skip initial '-'   */
     switch (**argv) {
        case 'a': fputs(About,stderr);  exit(1);
        case 'n': Language = NORWEGIAN; break;
        default : fputs(Usage,stderr);  exit(1);
     } /* switch */
     argc--; argv++;
  } /* while options */
  if (argc) { fputs(Usage,stderr); exit(1); }

  BEGIN 0;
  LineNo = 0;
  FNote = fopen("FN.TMP","w");
  /* BFile = fopen("references.tex","r"); */
  yylex();

  fclose(FNote);
  if (Fnumber) {
     char buff[80];
     FNote = fopen("FN.TMP","r");
     pfotnote();
     while (fgets(buff,80,FNote)) fputs(buff,stdout);
  } /* if */
  unlink("FN.TMP");
  puts("..EOF");
} /* main */

/*---( EOF lex input file )-------------------------------------------------*/