summaryrefslogtreecommitdiff
path: root/Build/source/texk/detex/detex-src/detex.l
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/detex/detex-src/detex.l')
-rw-r--r--Build/source/texk/detex/detex-src/detex.l162
1 files changed, 128 insertions, 34 deletions
diff --git a/Build/source/texk/detex/detex-src/detex.l b/Build/source/texk/detex/detex-src/detex.l
index 4b638f930cc..8273afe7a5b 100644
--- a/Build/source/texk/detex/detex-src/detex.l
+++ b/Build/source/texk/detex/detex-src/detex.l
@@ -41,7 +41,7 @@
/*
- * detex [-e environment-list] [-c] [-l] [-n] [-s] [-t] [-w] [file[.tex] ]
+ * 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.
@@ -95,13 +95,16 @@
%{
#undef IGNORE
+#undef ECHO
#define LaBEGIN if (fLatex) BEGIN
-#define IGNORE if (fSpace && !fWord) putchar(' ')
+#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 if (!fWord) putchar('\n')
+#define NEWLINE LineBreak()
#define LATEX fLatex=!fForcetex
#define KILLARGS(x) cArgs=x; LaBEGIN LaMacro
#define STRIPARGS(x) cArgs=x; LaBEGIN LaMacro2
@@ -109,6 +112,10 @@
#define NO_MALLOC_DECL
+void LineBreak();
+void Ignore();
+void IncrLineNo();
+void Echo();
void AddInclude(char *sbFile);
void ErrorExit(const char *sb1);
void UsageExit(void);
@@ -158,8 +165,9 @@ 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 fShowPictures = 0; /* flag to show picture names */
-int fReplace = 0; /* flag to replace envirnments with "noun" */
+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;
@@ -169,8 +177,11 @@ int footnoteLevel = -100;
* 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 */
+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 */
%}
@@ -179,6 +190,7 @@ 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})?
@@ -194,7 +206,7 @@ VERBSYMBOL =|\\leq|\\geq|\\in|>|<|\\subseteq|\subseteq|\\subset|\\supset|\\sim|\
%start LaBreak LaPicture
%%
-<Normal>"%".* /* ignore comments */ ;
+<Normal>"%".* /* ignore comments */ {INCRLINENO;}
<Normal>"\\begin"{S}"{"{S}"document"{S}"}""\n"* {LATEX; IGNORE;}
@@ -219,7 +231,7 @@ VERBSYMBOL =|\\leq|\\geq|\\in|>|<|\\subseteq|\subseteq|\\subset|\\supset|\\sim|\
IGNORE;
}
-<LaBegin>{S}"{"{S}"table"{S}"}"{S}"["{W}"]" {
+<LaBegin>{S}"{"{S}"table"{S}"}"{S}"["{P}"]" {
if (BeginEnv("table"))
BEGIN LaEnv;
else
@@ -227,7 +239,7 @@ VERBSYMBOL =|\\leq|\\geq|\\in|>|<|\\subseteq|\subseteq|\\subset|\\supset|\\sim|\
IGNORE;
}
-<LaBegin>{S}"{"{S}"figure"{S}"}"{S}"["{W}"]" {
+<LaBegin>{S}"{"{S}"figure"{S}"}"{S}"["{P}"]" {
if (BeginEnv("figure"))
BEGIN LaEnv;
else
@@ -242,11 +254,11 @@ VERBSYMBOL =|\\leq|\\geq|\\in|>|<|\\subseteq|\subseteq|\\subset|\\supset|\\sim|\
IGNORE;
}
/*<LaBegin>"\n" NEWLINE;*/
-<LaBegin>. ;
+<LaBegin>. {INCRLINENO;}
<LaEnv>"\\end" /* absorb some environments */ {LaBEGIN LaEnd; IGNORE;}
<LaEnv>"\n"+ ;/*NEWLINE;*/
-<LaEnv>. ;
+<LaEnv>. {INCRLINENO;}
<LaEnd>{W} /* end environment */ { if (EndEnv(yytext))
BEGIN Normal;
@@ -254,7 +266,7 @@ VERBSYMBOL =|\\leq|\\geq|\\in|>|<|\\subseteq|\subseteq|\\subset|\\supset|\\sim|\
}
<LaEnd>"}" {BEGIN LaEnv; IGNORE;}
/*<LaEnd>"\n" NEWLINE;*/
-<LaEnd>. ;
+<LaEnd>. {INCRLINENO;}
<Normal>"\\kern"{HD} ;
<Normal>"\\vskip"{VG} ;
@@ -284,7 +296,7 @@ VERBSYMBOL =|\\leq|\\geq|\\in|>|<|\\subseteq|\subseteq|\\subset|\\supset|\\sim|\
<LaPicture>"{" ;
<LaPicture>[^{}]+ { if(fShowPictures) { printf("<Picture %s>", yytext); } }
-<LaPicture>"\}"{S}"\n"+ BEGIN Normal;
+<LaPicture>"\}"{S}"\n"+ { BEGIN Normal; INCRLINENO; }
<LaPicture>"\}" BEGIN Normal;
<Normal>"\\definecolor" { KILLARGS(3); }
@@ -458,13 +470,13 @@ VERBSYMBOL =|\\leq|\\geq|\\in|>|<|\\subseteq|\subseteq|\\subset|\\supset|\\sim|\
ECHO;
}
<Normal>[0-9]+ if (!fWord) ECHO;
-<Normal>. if (!fWord) ECHO;
-<Normal>"\n" if (!fWord) NEWLINE;
+<Normal>. { INCRLINENO; if (!fWord) ECHO; }
+<Normal>"\n" { if (!fWord) NEWLINE; }
<Normal>("\t")+ if (!fWord) putchar('\t');
<LaMacro>"\[" { BEGIN LaOptArg; }
<LaMacro>"{" { cOpenBrace++; }
-<LaMacro>"}""\n"{0,1} { cOpenBrace--;
+<LaMacro>"}""\n"{0,1} { cOpenBrace--; INCRLINENO;
if (cOpenBrace == 0)
{
if (--cArgs==0)
@@ -504,6 +516,7 @@ VERBSYMBOL =|\\leq|\\geq|\\in|>|<|\\subseteq|\subseteq|\\subset|\\supset|\\sim|\
** -s replace control sequences with space
** -t force tex mode
** -w word only output
+** -1 output some location information
** Set the list of LaTeX environments to ignore.
** Process each input file.
** If no input files are specified on the command line, process stdin.
@@ -577,6 +590,9 @@ main(int cArgs, char *rgsbArgs[])
case CHVERSIONOPT:
VersionExit();
break;
+ case CHSRCLOC:
+ fSrcLoc = 1;
+ break;
default:
sbBadOpt[0] = *pch;
sbBadOpt[1] = '\0';
@@ -598,6 +614,8 @@ main(int cArgs, char *rgsbArgs[])
Warning("can't open file", rgsbArgs[iArgs]);
continue;;
}
+ fFileNames[csb] = rgsbArgs[iArgs];
+ fFileLines[csb] = 1;
BEGIN Normal;
(void)yylex();
}
@@ -636,6 +654,7 @@ yywrap(void)
#ifdef FLEX_SCANNER
/* Pop context state */
if (csb > 0) {
+ free(fFileNames[csb]);
yy_delete_buffer( YY_CURRENT_BUFFER );
yy_switch_to_buffer( rgsb[--csb] );
}
@@ -665,6 +684,74 @@ yyless(int n)
#endif
/******
+** PrintPrefix -- In case fSrcLoc is 1 and we are about to
+** print the first column of a line, we want to output the location of
+** that line in the original LaTeX document it came from.
+******/
+
+void
+PrintPrefix()
+{
+ if (fSrcLoc && fIsColumn0) {
+ printf("%s:%d: ", fFileNames[csb], fFileLines[csb]);
+ fIsColumn0 = 0;
+ }
+}
+
+/******
+** LineBreak -- choses the proper way to break a line. If '-1' option is
+** enabled we also want to output some source location information.
+******/
+
+void
+LineBreak()
+{
+ if (fWord) return;
+ PrintPrefix();
+ putchar('\n');
+ fFileLines[csb]++; fIsColumn0=1;
+}
+
+/******
+** Echo -- If we are at column 0 and have specified '-1'; output
+** the source location information.
+******/
+
+void
+Echo()
+{
+ PrintPrefix();
+ fprintf(yyout, "%s", yytext);
+}
+
+/******
+** IncrLineNo -- Increase the correct linenumber counter and
+** reset the the 'fIsColumn0' to true.
+******/
+
+void
+IncrLineNo()
+{
+ for (char* c=yytext; *c != '\0'; c++) {
+ if (*c == '\n') {
+ fFileLines[csb]++; fIsColumn0=1;
+ }
+ }
+}
+
+/******
+** Ignore -- Since we might need to track source location information we
+** cannot just ignore text. We must at least increase the linenumber counter.
+******/
+
+void
+Ignore()
+{
+ IncrLineNo();
+ if (fSpace && !fWord) putchar(' ');
+}
+
+/******
** SetEnvIgnore -- sets rgsbEnvIgnore to the values indicated by the
** sbEnvList.
******/
@@ -719,6 +806,7 @@ EndEnv(const char *sbEnv)
** the sbFile is ignored.
******/
+
void
InputFile(char *sbFile)
{
@@ -733,8 +821,10 @@ InputFile(char *sbFile)
return;
}
#ifdef FLEX_SCANNER
- rgsb[csb++] = YY_CURRENT_BUFFER;
- yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) );
+ rgsb[csb++] = YY_CURRENT_BUFFER;
+ fFileLines[csb] = 1;
+ fFileNames[csb] = strdup(sbFile);
+ yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) );
#endif /* FLEX_SCANNER */
}
@@ -759,8 +849,10 @@ IncludeFile(char *sbFile)
return;
}
#ifdef FLEX_SCANNER
- rgsb[csb++] = YY_CURRENT_BUFFER;
- yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) );
+ rgsb[csb++] = YY_CURRENT_BUFFER;
+ fFileLines[csb] = 1;
+ fFileNames[csb] = strdup(sbFile);
+ yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) );
#endif /* FLEX_SCANNER */
}
@@ -898,24 +990,25 @@ TexOpen(char *sbFile)
#else
if (*sbFile == '/') { /* absolute path */
#endif
- (void)sprintf(sbFullPath, "%s", sbFile);
- iPath = csbInputPaths; /* only check once */
- } else
- (void)sprintf(sbFullPath, "%s/%s", rgsbInputPaths[iPath], sbFile);
+ (void)snprintf(sbFullPath, PATH_MAX-1, "%s", sbFile);
+ iPath = csbInputPaths; /* only check once */
+ } else {
+ (void)snprintf(sbFullPath, PATH_MAX-1, "%s/%s", rgsbInputPaths[iPath], sbFile);
+ }
#ifdef OS2
pch = sbFullPath;
- while (pch = strchr(pch, '\\'))
- *pch = '/';
+ while (pch = strchr(pch, '\\')) {
+ *pch = '/';
+ }
#endif
/* If sbFile ends in .tex then it must be there */
if ((pch = strrchr(sbFullPath, '.')) != NULL
- && (strcmp(pch, ".tex") == 0))
- {
- if ((fp = fopen(sbFullPath, "r")) != NULL)
- return(fp);
- else
- continue;
+ && (strcmp(pch, ".tex") == 0)) {
+ if ((fp = fopen(sbFullPath, "r")) != NULL)
+ return(fp);
+ else
+ continue;
}
/* if .<ext> then try to open it. the '.' represents */
@@ -996,7 +1089,7 @@ ErrorExit(const char *sb1)
void
UsageExit(void)
{
- (void)printf("\n%s [ -clnrstw ] [ -e environment-list ] [ filename[.tex] ... ]\n",
+ (void)printf("\n%s [ -clnrstw1 ] [ -e environment-list ] [ filename[.tex] ... ]\n",
sbProgName);
puts(" -c echo LaTeX \\cite, \\ref, and \\pageref values\n \
-e <env-list> list of LaTeX environments to ignore\n \
@@ -1006,6 +1099,7 @@ UsageExit(void)
-s replace control sequences with space\n \
-t force tex mode\n \
-w word only output\n \
+-1 outputs the original file name and line number in the beginning of each line\n \
-v show program version and exit");
exit(0);
}