summaryrefslogtreecommitdiff
path: root/support/schemetex/schemetex.l
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/schemetex/schemetex.l
Initial commit
Diffstat (limited to 'support/schemetex/schemetex.l')
-rw-r--r--support/schemetex/schemetex.l190
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);
+}