%option never-interactive %top{ #ifndef lint static char rcsid[] = "$Header: /p/src/local/bin/detex/RCS/detex.l,v 2.22 2007/03/01 20:22:01 trinkle Exp trinkle $"; #endif /* * Copyright (c) 1986-2007 Purdue University * All rights reserved. * * Developed by: Daniel Trinkle * Department of Computer Science, Purdue University * http://www.cs.purdue.edu/ * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal with the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * o Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimers. * * o Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * * o Neither the names of Daniel Trinkle, Purdue University, nor the * names of its contributors may be used to endorse or promote products * derived from this Software without specific prior written * permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. */ /* * detex [-e environment-list] [-c] [-l] [-n] [-s] [-t] [-w] [file[.tex] ] * * This program is used to remove TeX or LaTeX constructs from a text * file. */ #include "detex.h" #ifdef KPATHSEA #include #include #include #include #include #include #include #ifdef HAVE_SYS_PARAM_H #include #endif #else /* KPATHSEA */ #ifdef HAVE_STRING_H #include #else #include #define strchr index #define strrchr rindex #endif #ifndef MAXPATHLEN #include #endif #define PATH_MAX MAXPATHLEN #ifdef OS2 #include #endif #ifdef WIN32 #include #include #endif #endif /* KPATHSEA */ } %{ #undef IGNORE #define LaBEGIN if (fLatex) BEGIN #define IGNORE if (fSpace && !fWord) putchar(' ') #define SPACE if (!fWord) putchar(' ') #define NEWLINE if (!fWord) putchar('\n') #define LATEX fLatex=!fForcetex #define KILLARGS(x) cArgs=x; LaBEGIN LaMacro #define STRIPARGS(x) cArgs=x; LaBEGIN LaMacro2 #define CITE(x) if (fLatex && !fCite) KILLARGS(x) void AddInclude(char *sbFile); void ErrorExit(const char *sb1); void IncludeFile(char *sbFile); void InputFile(char *sbFile); void SetEnvIgnore(const char *sbEnvList); #ifndef KPATHSEA void SetInputPaths(void); #endif void Warning(const char *sb1, const char *sb2); int BeginEnv(const char *sbEnv); int EndEnv(const char *sbEnv); int InList(char *sbFile); int SeparateList(char *sbList, char *rgsbList[] ,char chSep, int csbMax); FILE *TexOpen(char *sbFile); char *SafeMalloc(int cch, const char *sbMessage); #ifndef KPATHSEA char *getenv(); #ifndef NO_MALLOC_DECL char *malloc(); #endif #ifdef OS2 void yyless(int); void OS2UsageExit(void); #endif #endif /* KPATHSEA */ char *rgsbEnvIgnore[MAXENVS]; /* list of environments ignored */ char *rgsbIncList[MAXINCLIST]; /* list of includeonly files */ char *rgsbInputPaths[MAXINPUTPATHS]; /* list of input paths in order */ char sbCurrentEnv[CCHMAXENV]; /* current environment being ignored */ char *sbProgName; /* name we were invoked with */ #ifndef NOFILE /* might be defined in */ #define NOFILE 256 #endif FILE *rgfp[NOFILE+1]; /* stack of input/include files */ int cfp = 0; /* count of files in stack */ int cOpenBrace = 0; /* count of `{' in and */ int cArgs = 0; /* argument connt in */ int csbEnvIgnore; /* count of environments ignored */ int csbIncList = 0; /* count of includeonly files */ int csbInputPaths; /* count of input paths */ int fLatex = 0; /* flag to indicated delatex */ int fWord = 0; /* flag for -w option */ int fFollow = 1; /* flag to follow input/include */ int fCite = 0; /* flag to echo \cite and \ref args */ int fSpace = 0; /* flag to replace \cs with space */ int fForcetex = 0; /* flag to inhibit latex mode */ #ifdef FLEX_SCANNER /* flex has contexts for buffers that need to be switched when file changes * otherwise output contains imported files in reverse order. Weird, but * true. */ YY_BUFFER_STATE rgsb[NOFILE + 1]; /* flex context stack */ int csb = 0; /* depth of flex context stack */ #endif /* FLEX_SCANNER */ %} S [ \t\n]* W [a-zA-Z]+ N [+-]?(([0-9]+(\.[0-9]+)?)|(\.[0-9]+)) U pt|pc|in|bp|cm|mm|dd|cc|sp HU {U}|em HD {S}(({N}{S}{HU})|(\\{W})){S} HG {HD}(plus{HD})?(minus{HD})? VU {U}|ex VD {S}(({N}{S}{VU})|(\\{W})){S} VG {VD}(plus{VD})?(minus{VD})? Z \*? %Start Define Display IncludeOnly Input Math Normal Control %Start LaBegin LaDisplay LaEnd LaEnv LaFormula LaInclude %Start LaMacro LaOptArg LaMacro2 LaOptArg2 LaVerbatim %start LaBreak LaPicture %% "%".* /* ignore comments */ ; "\\begin"{S}"{"{S}"document"{S}"}" {LATEX; IGNORE;} "\\begin" /* environment start */ {LaBEGIN LaBegin; IGNORE;} {S}"{"{S}"verbatim"{S}"}" { if (BeginEnv("verbatim")) BEGIN LaEnv; else BEGIN LaVerbatim; IGNORE; } "\\end"{S}"{"{S}"verbatim"{S}"}" /* verbatim mode */ {BEGIN Normal; IGNORE;} [^\\]+ ECHO; . ECHO; {S}"{"{S}"minipage"{S}"}" { KILLARGS(1); if (BeginEnv("minpage")) BEGIN LaEnv; else BEGIN Normal; IGNORE; } {W} { if (BeginEnv(yytext)) BEGIN LaEnv; else BEGIN Normal; IGNORE; } "\n" NEWLINE; . ; "\\end" /* absorb some environments */ {LaBEGIN LaEnd; IGNORE;} "\n" NEWLINE; . ; {W} /* end environment */ { if (EndEnv(yytext)) BEGIN Normal; IGNORE; } "}" {BEGIN LaEnv; IGNORE;} "\n" NEWLINE; . ; "\\kern"{HD} ; "\\vskip"{VG} ; "\\vspace"{Z}{S}"{"{VG}"}" ; "\\hskip"{HG} ; "\\hspace"{Z}{S}"{"{HG}"}" ; "\\addvspace"{S}"{"{VG}"}" ; "\\newlength" { KILLARGS(1); } "\\setlength" { KILLARGS(2); } "\\addtolength" { KILLARGS(2); } "\\settowidth" { KILLARGS(2); } "\\settoheight" { KILLARGS(2); } "\\settodepth" { KILLARGS(2); } "\\newsavebox" { KILLARGS(1); } "\\sbox" { KILLARGS(1); } "\\savebox" { KILLARGS(2); } "\\usebox" { KILLARGS(1); } "\\raisebox" { STRIPARGS(2); } "\\parbox" { KILLARGS(1); } "\\scalebox" { STRIPARGS(2); } "\\resizebox"{Z} { KILLARGS(2); } "\\reflectbox" ; "\\rotatebox" { KILLARGS(1); } "\\includegraphics"[^{]* { LaBEGIN LaPicture; } "{" ; [^{}]+ { printf("", yytext); } "\}" BEGIN Normal; "\\definecolor" { KILLARGS(3); } "\\color" { KILLARGS(1); } "\\textcolor" { KILLARGS(2); } "\\colorbox" { KILLARGS(2); } "\\fcolorbox" { KILLARGS(3); } "\\pagecolor" { KILLARGS(1); } "\\foilhead" { STRIPARGS(1); } "\\part"{Z} ; "\\section"{Z} ; "\\subsection"{Z} ; "\\subsubsection"{Z} ; "\\paragraph"{Z} ; "\\sunparagraph"{Z} ; "\\bibitem" /* ignore args */ {KILLARGS(1); IGNORE;} "\\bibliography" /* of these \cs */ {KILLARGS(1); IGNORE;} "\\bibstyle" {KILLARGS(1); IGNORE;} "\\cite" {CITE(1); IGNORE;} "\\documentstyle" {LATEX; KILLARGS(1); IGNORE;} "\\documentclass" {LATEX; KILLARGS(1); IGNORE;} "\\usepackage" {KILLARGS(1); IGNORE;} "\\end" {KILLARGS(1); IGNORE;} "\\index" {KILLARGS(1); SPACE;} "\\footnote" {KILLARGS(1); SPACE;} "\\label" {KILLARGS(1); IGNORE;} "\\pageref" {CITE(1); IGNORE;} "\\pagestyle" {KILLARGS(1); IGNORE;} "\\ref" {CITE(1); IGNORE;} "\\setcounter" {KILLARGS(1); IGNORE;} "\\verb" /* ignore \verb... */ { if (fLatex) { char verbchar, c; verbchar = input(); while ((c = input()) != verbchar) if (c == '\n') NEWLINE; } IGNORE; } "\\newcommand" { LATEX; KILLARGS(2); } "\\renewcommand" { LATEX; KILLARGS(2); } "\\newenvironment" { LATEX; KILLARGS(3); } "\\def" /* ignore def begin */ {BEGIN Define; IGNORE;} "{" BEGIN Normal; "\n" NEWLINE; . ; "\\(" /* formula mode */ {LaBEGIN LaFormula; IGNORE;} "\\)" BEGIN Normal; "\n" NEWLINE; . ; "\\[" /* display mode */ {LaBEGIN LaDisplay; IGNORE;} "\\]" BEGIN Normal; "\n" NEWLINE; . ; "$$" /* display mode */ {BEGIN Display; IGNORE;} "$$" BEGIN Normal; "\n" NEWLINE; . ; "$" /* math mode */ {BEGIN Math; IGNORE;} "$" BEGIN Normal; "\n" NEWLINE; "\\$" ; . ; "\\include" /* process files */ {LaBEGIN LaInclude; IGNORE;} [^{ \t\n}]+ { IncludeFile(yytext); BEGIN Normal; } "\n" NEWLINE; . ; "\\includeonly" {BEGIN IncludeOnly; IGNORE;} [^{ \t,\n}]+ AddInclude(yytext); "}" { if (csbIncList == 0) rgsbIncList[csbIncList++] = '\0'; BEGIN Normal; } "\n" NEWLINE; . ; "\\input" {BEGIN Input; IGNORE;}