%option never-interactive %option nounput %top{ /* * 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] [-1] [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 strrchr rindex #endif #ifdef HAVE_LIMITS_H #include #else #include #ifndef PATH_MAX /* for old BSD */ #define PATH_MAX MAXPATHLEN #endif #endif /* HAVE_LIMITS_H */ #ifdef OS2 #include #endif #ifdef WIN32 #include #include #endif #endif /* KPATHSEA */ } %{ #undef IGNORE #undef ECHO #define LaBEGIN if (fLatex) BEGIN #define IGNORE Ignore() #define INCRLINENO IncrLineNo() #define ECHO Echo() #define NOUN if (fSpace && !fWord && !fReplace) putchar(' '); else {if (fReplace) printf("noun");} #define VERBNOUN if (fReplace) printf(" verbs noun"); /* puts a verb and a noun to make grammar checking work */ #define SPACE if (!fWord) putchar(' ') #define NEWLINE LineBreak() #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) #define NO_MALLOC_DECL void LineBreak(); void Ignore(); void IncrLineNo(); void Echo(); void AddInclude(char *sbFile); void ErrorExit(const char *sb1); void UsageExit(void); void VersionExit(void); 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 sbCurrentIgnoredEnv[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 */ int fSrcLoc = 0; /* flag to display source location of original file */ int fShowPictures = 0; /* flag to show picture names */ int fReplace = 0; /* flag to replace envirnments with "noun" */ int currBracesLevel = 0; int footnoteLevel = -100; #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 */ char* fFileNames[NOFILE + 1]; /* names of the buffers in context stack */ int fFileLines[NOFILE + 1]; /* line number in each of the context files */ int fIsColumn0 = 1; /* Are we at the begining of a line? */ 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 P [a-zA-Z!]+ 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 \*? VERBSYMBOL =|\\leq|\\geq|\\in|>|<|\\subseteq|\subseteq|\\subset|\\supset|\\sim|\\neq|\\mapsto %Start Define Display IncludeOnly Input Math Normal Control %Start LaBegin LaDisplay LaEnd LaEnv LaFormula LaInclude LaSubfile %Start LaMacro LaOptArg LaMacro2 LaOptArg2 LaVerbatim %start LaBreak LaPicture %% "%".* /* ignore comments */ {INCRLINENO;} "\\begin"{S}"{"{S}"document"{S}"}""\n"* {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("minipage")) BEGIN LaEnv; else BEGIN LaMacro; /* Normal; */ IGNORE; } {S}"{"{S}"table"{S}"}"{S}"["{P}"]" { if (BeginEnv("table")) BEGIN LaEnv; else BEGIN Normal; IGNORE; } {S}"{"{S}"figure"{S}"}"{S}"["{P}"]" { if (BeginEnv("figure")) BEGIN LaEnv; else BEGIN Normal; IGNORE; } {W} { if (BeginEnv(yytext)) BEGIN LaEnv; else BEGIN Normal; IGNORE; } /*"\n" NEWLINE;*/ . {INCRLINENO;} "\\end" /* absorb some environments */ {LaBEGIN LaEnd; IGNORE;} "\n"+ ;/*NEWLINE;*/ . {INCRLINENO;} {W} /* end environment */ { if (EndEnv(yytext)) BEGIN Normal; IGNORE; } "}" {BEGIN LaEnv; IGNORE;} /*"\n" NEWLINE;*/ . {INCRLINENO;} "\\kern"{HD} ; "\\vskip"{VG} ; "\\vspace"{Z}{S}"{"{VG}"}" ; "\\hskip"{HG} ; "\\hspace"{Z}{S}"{"{HG}"}" ; "\\addvspace"{S}"{"{VG}"}" ; "{"{N}"pt}" ; /* hack to fix \begin{minipage}{300pt} */ "\\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; } "{" ; [^{}]+ { if(fShowPictures) { printf("", yytext); } } "\}"{S}"\n"+ { BEGIN Normal; INCRLINENO; } "\}" BEGIN Normal; "\\definecolor" { KILLARGS(3); } "\\color" { KILLARGS(1); } "\\textcolor" { KILLARGS(2); } "\\colorbox" { KILLARGS(2); } "\\fcolorbox" { KILLARGS(3); } "\\pagecolor" { KILLARGS(1); } "\\foilhead" { STRIPARGS(1); } "\\addfontfeature" { KILLARGS(1); } "\\thispagestyle" { KILLARGS(1); } "\\addcontentsline" { KILLARGS(3); } "\\part"{Z} ;/*NEWLINE;*/ "\\chapter"{Z} ;/*NEWLINE;*/ "\\section"{Z} ;/*NEWLINE;*/ "\\subsection"{Z} ;/*NEWLINE;*/ "\\subsubsection"{Z} ;/*NEWLINE;*/ "\\paragraph"{Z} ;/*NEWLINE;*/ "\\subparagraph"{Z} ;/*NEWLINE;*/ "\\bibitem" /* ignore args */ {KILLARGS(1); IGNORE;} "\\bibliography" /* of these \cs */ {KILLARGS(1); IGNORE;} "\\bibstyle" {KILLARGS(1); IGNORE;} " "?"\\cite" {KILLARGS(1);} /* kill space before */ "\\documentstyle" {LATEX; KILLARGS(1); IGNORE;} "\\documentclass" {LATEX; KILLARGS(1); IGNORE;} "\\usepackage" {KILLARGS(1); IGNORE;} "\\end" {KILLARGS(1); IGNORE;} "\\hypersetup" {KILLARGS(1);} "\\index" {KILLARGS(1);} /*"\\footnote" {KILLARGS(1); SPACE;}*/ "\\label" {KILLARGS(1); IGNORE;} "\\nameref" {CITE(1); IGNORE;} "\\pageref" {CITE(1); IGNORE;} "\\pagestyle" {KILLARGS(1); IGNORE;} "\\ref" {CITE(1); IGNORE;} "\\setcounter" {KILLARGS(2); IGNORE;} "\\addtocounter" {KILLARGS(2); IGNORE;} "\\newcounter" { KILLARGS(1); } "\\stepcounter" { KILLARGS(2); } "\\fontspec" {KILLARGS(1);} "\\footnote"(\[([^\]])+\])?"{" { putchar('('); footnoteLevel = currBracesLevel; ++currBracesLevel; } "\\verb" /* ignore \verb... */ { if (fLatex) { char verbchar, c; verbchar = input(); while ((c = input()) != verbchar) /*if (c == '\n') NEWLINE;*/ putchar(c); } 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; NOUN;} "\\)" BEGIN Normal; "\n" NEWLINE; {VERBSYMBOL} VERBNOUN; . ; "\\[" /* display mode */ {LaBEGIN LaDisplay; NOUN;} "\\]" BEGIN Normal; "\n" NEWLINE; {VERBSYMBOL} VERBNOUN; . ; "$$" /* display mode */ {BEGIN Display; NOUN;} "$$" BEGIN Normal; "\n" NEWLINE; {VERBSYMBOL} VERBNOUN; . ; "$" /* math mode */ {BEGIN Math; NOUN;} "$" BEGIN Normal; "\n" ; "\\$" ; {VERBSYMBOL} VERBNOUN; . ; "\\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; . ; "\\subfile" /* process files */ {LaBEGIN LaSubfile; IGNORE;} [^{ \t\n}]+ { IncludeFile(yytext); BEGIN Normal; } "\n"+ NEWLINE; . ; "\\input" {BEGIN Input; IGNORE;}