diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/schemetex/schemetex.l |
Initial commit
Diffstat (limited to 'support/schemetex/schemetex.l')
-rw-r--r-- | support/schemetex/schemetex.l | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/support/schemetex/schemetex.l b/support/schemetex/schemetex.l new file mode 100644 index 0000000000..f00087c969 --- /dev/null +++ b/support/schemetex/schemetex.l @@ -0,0 +1,190 @@ +%{ +/* schemeTeX -- Scheme to TeX. John D. Ramsdell. + * Simple support for literate programming in Scheme. + * Usage: schemeTeX < {Scheme TeX file} > {TeX file} + */ + +#if !defined lint +static char ID[] = "@(#)schemeTeX.l 1.3 88/06/30"; +static char copyright[] = "Copyright 1988 by The MITRE Corporation."; +/* Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies. The +MITRE Corporation makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. */ +#endif + +/* SchemeTeX defines a new source file format in which source lines +are divided into text and code. Lines of code start with a line +beginning with '(', and continue until the line that contains the +matching ')'. The text lines remain, and they are treated as +comments. If the first character of a text line is ';', it is +stripped from the output. This is provided for those who want to use +an unmodified version of their Scheme system's LOAD. When producing a +document, both the text lines and the code lines are copied into the +document source file, but the code lines are surrounded by a pair of +formatting commands, as is comments beginning with ';' within code +lines. SchemeTeX is currently set up for use with LaTeX. */ + +/* Define STRIP if you want to remove all comments in a Scheme TeX +file. */ + +/* Modify the following for use with something other than LaTeX. +Also see tex_verbatim_echo. */ +#define BEGIN_COMMENT "\\notastyped{" +#define BEGIN_CODE "\\begin{astyped}" +#define END_CODE "\\end{astyped}" +#define TEX_ECHO tex_verbatim_echo(yytext, stdout) +/* Lex is used for identifying code in an Scheme TeX file. */ +int parens; /* Used to balance parenthesis. */ + +/* All input occurs in the following routines so that TAB characters +can be expanded. TeX treats TAB characters as a space--not what is +wanted. */ +#undef getc() +#define getc(STREAM) expanding_getc(STREAM) +int spaces = 0; /* Spaces left to print a TAB. */ +int column = 0; /* Current input column. */ +int expanding_getc(stream) + FILE *stream; +{ + int c; + if (spaces > 0) { + spaces--; + return ' '; + } + switch (c = fgetc(stream)) { + case '\t': + spaces = 8 - (7&column); + column += spaces; + return expanding_getc(stream); + case '\n': + column = 0; + return c; + default: + column++; + return c; + } +} +%} +%% +#\\\( { +#if defined STRIP + ECHO; +#else + TEX_ECHO; +#endif + } +#\\\) { +#if defined STRIP + ECHO; +#else + TEX_ECHO; +#endif + } +\( { ECHO; parens++; } +\) { ECHO; parens--; + if (parens == 0) { /* End of code. */ + char c; /* Check that nothing follows. */ + while ((c = input()) == ' ') output(c); + if (c == '\000') return 0; /* EOF */ + if (c != '\n' && c != ';') return -1; + unput(c); + } + } +\"[^"]*\" { + if ((yyleng > 1) && (yytext[yyleng-2] == '\\')) + yymore(); + else +#if defined STRIP + ECHO; +#else + TEX_ECHO; +#endif + } +;[^\n]*$ { +#if defined STRIP + ; +#else + fputs(BEGIN_COMMENT, stdout); + ECHO; + fputs("}", stdout); +#endif + } +\n { ECHO; if (parens <= 0) return 0; } +. { +#if defined STRIP + ECHO; +#else + TEX_ECHO; +#endif + } +%% + +fatal (s) + char *s; +{ + fprintf(stderr, "On line %d, %s\n", yylineno, s); + exit(1); +} + +tex_verbatim_echo (s, f) + char *s; FILE *f; +{ + for (; *s != '\000'; s++) + switch (*s) { + case '\\': + case '{': + case '}': + case '$': + case '&': + case '#': + case '^': + case '_': + case '%': + case '~': + fputs("\\verb-", f); + putc(*s, f); + putc('-', f); + break; + default: putc(*s, f); + } +} + +main() +{ + char c; + do { /* TeX mode and saw newline */ + c = input(); + if (c == '(') { /* TeX mode changed to code mode. */ + unput(c); +#if !defined STRIP + fputs(BEGIN_CODE,stdout); putc('\n', stdout); +#endif + do { /* Copy out code using yylex. */ + parens = 0; + if (0 != yylex()) fatal("Bad code section."); + if (parens != 0) fatal("Premature EOF."); + c = input(); + unput(c); /* Repeat when there is code */ + } while (c == '('); /* immediately after copied code. */ +#if !defined STRIP + fputs(END_CODE, stdout); putc('\n', stdout); +#endif + } + else { /* Found a text line. */ + if (c == ';') c = input(); /* For those who want to use bare load. */ + while (c != '\n') { + if (c == '\000') exit(0); /* EOF. */ +#if !defined STRIP + output(c); +#endif + c = input(); + } +#if !defined STRIP + output(c); +#endif + } + } while (1); +} |