summaryrefslogtreecommitdiff
path: root/support/s2latex
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/s2latex
Initial commit
Diffstat (limited to 'support/s2latex')
-rw-r--r--support/s2latex/Makefile21
-rw-r--r--support/s2latex/README14
-rw-r--r--support/s2latex/README.TOO29
-rw-r--r--support/s2latex/s2l.l159
-rw-r--r--support/s2latex/s2l.y550
-rw-r--r--support/s2latex/s2latex.patch95
-rw-r--r--support/s2latex/s2latex.tbl209
-rw-r--r--support/s2latex/symtab.c76
-rw-r--r--support/s2latex/symtab.h15
-rw-r--r--support/s2latex/win32/s2latex-win32.readme30
10 files changed, 1198 insertions, 0 deletions
diff --git a/support/s2latex/Makefile b/support/s2latex/Makefile
new file mode 100644
index 0000000000..615a3d8e0b
--- /dev/null
+++ b/support/s2latex/Makefile
@@ -0,0 +1,21 @@
+CFLAGS=-O
+
+all: s2latex s2latex.1
+
+s2latex: y.tab.c lex.yy.c symtab.o symtab.h
+ cc ${CFLAGS} -o s2latex y.tab.c symtab.o -ll
+
+y.tab.c: s2l.y
+ yacc s2l.y
+
+lex.yy.c: s2l.l
+ lex s2l.l
+
+s2latex.1: s2latex.tbl
+ tbl s2latex.tbl >s2latex.1
+
+clean:
+ rm -f y.tab.c lex.yy.c core y.tab.h *.o s2latex.1
+
+mktar:
+ tar cvf s2latex.tar Makefile s2l.y s2l.l symtab.c symtab.h s2latex.tbl
diff --git a/support/s2latex/README b/support/s2latex/README
new file mode 100644
index 0000000000..acba303327
--- /dev/null
+++ b/support/s2latex/README
@@ -0,0 +1,14 @@
+
+s2latex is a Scribe to LaTeX converter. It is expected to get about 90%
+right the first time it is run and then additions of translation rules will
+help get much more of the way along. See the Makefile for more details. It
+was written by Van Jacobson of Lawrence Berkeley Laboratory.
+
+To help prevent duplicated efforts, Van Jacobson has agreed to coordinate
+accepting contributions of additional translation rules. If you find
+yourself writing a translation rule that you think is of general usefulness,
+please send it to him---his net address is van@lbl-csam. Identifying
+commonly needed translation rules will be of benefit as well since they can
+be added to the default set provided by the program.
+
+
diff --git a/support/s2latex/README.TOO b/support/s2latex/README.TOO
new file mode 100644
index 0000000000..0fe24918a3
--- /dev/null
+++ b/support/s2latex/README.TOO
@@ -0,0 +1,29 @@
+
+This is what I have been able to assemble of what was apparently a
+full distribution of s2latex, a converter for turning Scribe text into
+LaTeX-compatible files. I have been unable to test the converter (we
+don't have Scribe here), and the files that I received were evidently
+incomplete. The original author (Van Jacobson) is unreachable by
+E-mail.
+
+The most glaring lacuna was the fact that the file s2l.y did not end
+in a newline. Its last line looked like this:
+
+#include "lex.yy.c<end of file>
+
+I have appended a double quote and a newline to this file; that way,
+the thing at least compiles and links. Nonetheless, one has to
+suspect that other stuff might be missing as well, and since I can't
+test the executable, I can give no guarantee.
+
+When you do a make, you will get a yacc message about 81 shift/reduce
+and 48 reduce/reduce conflicts. According to the comments in the file
+s2l.y, this can be ignored.
+
+If you get the s2latex program to work, please let me know; also tell
+me whether you're satisfied with it. In particular, if you make
+changes to the sources to get it to work, please pass them on to me,
+in case someone else should ask for the program.
+
+-- Mark James <mark@bdblues.altair.fr> or <mark@nuri.inria.fr>
+
diff --git a/support/s2latex/s2l.l b/support/s2latex/s2l.l
new file mode 100644
index 0000000000..966a505c8a
--- /dev/null
+++ b/support/s2latex/s2l.l
@@ -0,0 +1,159 @@
+
+%{
+/* s2l.l 1.2 85/02/04 */
+/* scanner for "scribe" documents.
+ *
+ * copyright (c) 1984 by Van Jacobson, Lawrence Berkeley Laboratory
+ * This program may be freely redistributed but not for profit. This
+ * comment must remain in the program or any derivative.
+ */
+
+static char bstack[256]; /* the type of closing bracket we want */
+static int bsp = 0; /* "bracket" stack pointer */
+char matching();
+%}
+WS [ \t]*
+LB ("("|"["|"{"|"<"|\'|\"|\`)
+RB (")"|"]"|"}"|">"|\'|\"|\')
+%START CS BS B C
+%%
+@[bB][lL][aA][nN][kK][sS][pP][aA][cC][eE]/{LB} {
+ BEGIN BS;
+ if ( lastsym=lookup(yytext) )
+ return (lastsym->s_type);
+ fprintf(stderr,"lex botch: keyword %s\n", yytext );
+ exit(1);
+ }
+@[bB][eE][gG][iI][nN]{WS}{LB} return(get_env_name());
+@[eE][nN][dD]{WS}{LB} {
+ get_env_name();
+ return(END_ENV);
+ }
+@[a-zA-Z0-9]+/{WS}{LB} {
+ BEGIN CS;
+ if ( !(lastsym=lookup(yytext)) )
+ {
+ if ( kflag )
+ fprintf(stderr,"unknown keyword %s\n",
+ yytext );
+ lastsym = enter( yytext, KW_REP, &yytext[1] );
+ }
+ return (lastsym->s_type);
+ }
+@[a-zA-Z0-9]+ return(COMMAND);
+@\+/{WS}{LB} {
+ BEGIN CS;
+ return(SUP);
+ }
+@\-/{WS}{LB} {
+ BEGIN CS;
+ return(SUB);
+ }
+<CS>{WS} ;
+<CS>{LB} {
+ bstack[++bsp] = matching(*yytext);
+ BEGIN C;
+ return(LBRACK);
+ }
+<BS>{WS} ;
+<BS>{LB} {
+ bstack[++bsp] = matching(*yytext);
+ BEGIN B;
+ return(LBRACK);
+ }
+<B,C>{RB} {
+ if ( bstack[bsp] == *yytext ) {
+ if ( --bsp <= 0 )
+ BEGIN 0;
+ return(RBRACK);
+ }
+ return( (*yytext=='}'||*yytext=='"')? *yytext : CHAR );
+ }
+<B>[iI][nN][cC][hH][eE][sS] { return(INCHES); }
+@\\ return(TAB);
+@> return(RJUST);
+@= return(CENTER);
+@\\{WS}@= return(CENTER);
+@"^" return(SETTAB);
+@\\{WS}@=/{WS}\n ;
+@=/{WS}\n ;
+@\\/{WS}\n ;
+@; ;
+@~ return(STILDE);
+@_ return(HYPHEN);
+@" " return(NPSPACE);
+@@ return('@');
+@"*" return(LBREAK);
+@\.[ \t]+ return(POINT);
+@\.{WS}/\n return(POINT);
+[<>|{}#$%&~_^\\"] return(*yytext);
+. return(CHAR);
+^[ ]*\n {
+ inputline++;
+ return(BLANKLINE);
+ }
+[ ]*\n {
+ inputline++;
+ return('\n');
+ }
+%%
+yywrap() {
+ return (1);
+}
+
+/* get the "name" part of an environment spec & discard any optional
+ * parameters. The name is added to the symbol table if it isn't
+ * already there. At the time we call this routine, we've matched
+ * either "@begin{LB}" or "@end{LB}". We gobble input until we find
+ * the matching right bracket.
+ */
+get_env_name()
+{
+ char ename[128];
+ char c;
+ char *nm=ename;
+ char mb = matching( yytext[yyleng-1] );
+
+ /* get the name */
+ while ( isalnum( c=input() ) )
+ *nm++ = c;
+ *nm = '\0';
+
+ /* discard everything else up to the closing bracket */
+ while ( c != mb )
+ c = input();
+
+ /* lookup and/or add the env name */
+ if ( ! (lastsym = lookup(ename)) )
+ {
+ if ( kflag )
+ fprintf(stderr,"unknown environment %s\n", ename );
+ lastsym = enter( ename, ENV_REP, ename );
+ }
+ return(lastsym->s_type);
+}
+
+/* return the right bracket character that matches the given left bracket
+ * character.
+ */
+char matching(lb)
+char lb;
+{
+ switch(lb) {
+
+ case '(': return(')');
+ case '[': return(']');
+ case '{': return('}');
+ case '<': return('>');
+ case '"': return('"');
+ case '\'': return('\'');
+ case '`': return('\'');
+ default:
+ fprintf(stderr,"matching botch: '%c'\n", lb );
+ exit(1);
+ }
+}
+
+
+
+
diff --git a/support/s2latex/s2l.y b/support/s2latex/s2l.y
new file mode 100644
index 0000000000..7d08e278d8
--- /dev/null
+++ b/support/s2latex/s2l.y
@@ -0,0 +1,550 @@
+%{
+#ifndef lint
+static char *sccsid="@(#)s2l.y 1.2 (LBL) 2/4/85";
+#endif
+/* scribe-to-latex converter.
+ *
+ * copyright (c) 1984 by Van Jacobson, Lawrence Berkeley Laboratory
+ * This program may be freely redistributed but not for profit. This
+ * comment must remain in the program or any derivative.
+ *
+ * I would appreciate comments, suggestions, bug fixes, etc. My
+ * mailing addresses are:
+ * van@lbl-csam.arpa or van@lbl-rtsg.arpa (ARPANET or CSNET)
+ * ucbvax!lbl-csam!van (UUCP)
+ *
+ * Expect to get 81 shift/reduce & 48 reduce/reduce conflicts when
+ * running this thing through yacc. The grammar does more-or-less
+ * what I wanted so I didn't bother to add the precedence & assoc.
+ * rules needed to get rid of the confict msgs.
+ *
+ * Change this grammar with fear & trembling (I do). No text is
+ * kept around by the parser so the order of the reductions is very
+ * important. The reduction that outputs the current token has to
+ * happen before the next shift wipes out that token (except in some
+ * cases where the parse stack or the production encodes the token).
+ *
+ * Modifications.
+ * --------------
+ * 05Feb85, vj Bug fixes from users: added "comment" to allowed names
+ * in -s file; added "format" as kw in addition to env;
+ * fixed bug in kw->env handling; fixed mis-count of arguments
+ * when "-s" present.
+ * 30Dec84, vj Changed description env to handle null tags. Added
+ * a few more scribe 2-char control seq. to scanner.
+ * 28Dec84, vj Bug fixes from Richard Furuta
+ * 16Aug84 Van Jacobson, written.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <strings.h>
+#include "symtab.h"
+
+#define DELBUFLEN 1024 /* "delayed" text buffer length (see comments
+ * with routine "dprintf" */
+
+static struct stab *lastsym; /* result of last "lookup" */
+static int kflag = 0; /* set to print unrecog keywords */
+static int dirquote = 1; /* set to covert quotes to directed quotes */
+static int dquote=0; /* set 1 if we're expecting a closing double quote */
+static int informat=0; /* set 1 if we're doing a "format" environment */
+static int incomment=0; /* set 1 if we're inside a comment */
+static int delayout=0; /* set 1 if we have to delay output */
+static char *inputfile; /* current input file name */
+static inputline=1; /* line number in input file */
+%}
+%union {
+ int ival;
+ struct stab *sval;
+ }
+
+%token KW_REP /* keyword to be replaced */
+%token KW_ENV /* keyword to be made environment [begin()..end()] */
+%token KW_DEL /* keyword to be deleted */
+%token KW_COM /* comment */
+%token KW_FORMAT /* keyword introducing "format" environment */
+%token FONT /* keyword to be treated like font */
+%token KW_IGN /* keyword to ignore in @description label */
+%token ITEMIZE DESCRIPT
+%type <sval> kw_rep
+%type <sval> kw_env
+%type <sval> kw_format
+%type <sval> itemize
+%type <sval> descrip
+%type <sval> istart
+%type <sval> dstart
+%token ENV_REP /* environment to be renamed */
+%token ENV_DEL /* environment to be deleted */
+%token ENV_KW /* environment to be made keyword */
+%token ENV_FORMAT /* "format" (tabular) environment */
+%token END_ENV
+%token ENV_ITEMIZE
+%token ENV_DESCRIP
+%token ENV_COM /* comments */
+%type <sval> env_rep
+%type <sval> env_kw
+%type <sval> env_itemize
+%type <sval> env_descrip
+%type <sval> env_format
+%token BLANKLINE
+%token INCHES
+%token COMMAND
+%token SUP SUB
+%token TAB RJUST CENTER POINT NPSPACE SETTAB LBREAK STILDE HYPHEN
+%token CHAR
+%token LBRACK RBRACK
+%%
+sdoc : sdoc foo
+ | foo
+ ;
+foo : control
+ | ignore
+ | env
+ | special
+ | text
+ | error '\n'
+ ;
+control : kw_rep balbrack
+ | itemize optnl items RBRACK {
+ dprintf("\\end{%s}",$1->s_reptext);
+ }
+ | itemize optnl items blanklines RBRACK {
+ dprintf("\\end{%s}",$1->s_reptext);
+ }
+ | descrip optnl ditems RBRACK {
+ dprintf("\\end{%s}",$1->s_reptext);
+ }
+ | descrip optnl ditems blanklines RBRACK {
+ dprintf("\\end{%s}",$1->s_reptext);
+ }
+ | kw_del sdoc RBRACK
+ | kw_env LBRACK optnl sdoc RBRACK {
+ dprintf("\\end{%s}",$1->s_reptext);
+ }
+ | kw_format LBRACK optnl sdoc RBRACK {
+ dprintf("\\end{%s}",$1->s_reptext);
+ informat = 0;
+ }
+ | supsub balbrack { dprintf( "}$" ); }
+ | font sdoc rbrack
+ | kw_com sdoc RBRACK optnl { dprintf("}\n"); incomment=0; }
+ ;
+ignore : kw_ign balbrack
+ ;
+env : env_rep sdoc endenv
+ | env_format optnl sdoc endenv { informat = 0; }
+ | ENV_DEL sdoc END_ENV
+ | env_kw sdoc END_ENV { dprintf( "}" ); }
+ | env_itemize optnl items endenv
+ | env_itemize optnl items blanklines endenv
+ | env_descrip optnl ditems endenv
+ | env_descrip optnl ditems blanklines endenv
+ | env_com sdoc endenv optnl { dprintf("\n"); incomment=0; }
+ ;
+env_rep : ENV_REP { dprintf("\\begin{%s}",lastsym->s_reptext); }
+ ;
+env_format: ENV_FORMAT {
+ dprintf("\\begin{%s}\n",lastsym->s_reptext);
+ informat = 1;
+ }
+ ;
+endenv : END_ENV { dprintf("\\end{%s}",lastsym->s_reptext); }
+ ;
+env_kw : ENV_KW { dprintf("\\%s{",lastsym->s_reptext); }
+ ;
+env_com : ENV_COM {
+ dprintf("%% \\begin{%s}", lastsym->s_reptext);
+ incomment=1;
+ }
+ ;
+kw_com : KW_COM LBRACK {
+ dprintf("%% \\%s{", lastsym->s_reptext);
+ incomment=1;
+ }
+ ;
+kw_rep : KW_REP { dprintf("\\%s",lastsym->s_reptext); }
+ ;
+kw_ign : KW_IGN { dprintf("\\%s",lastsym->s_reptext); }
+ ;
+kw_del : KW_DEL LBRACK optnl
+ ;
+kw_env : KW_ENV {
+ dprintf("\\begin{%s}\n",lastsym->s_reptext);
+ $$ = lastsym;
+ }
+ ;
+kw_format: KW_FORMAT {
+ dprintf("\\begin{%s}\n",lastsym->s_reptext);
+ $$ = lastsym;
+ informat = 1;
+ }
+ ;
+itemize : istart LBRACK {
+ dprintf("\\begin{%s}\n",$1->s_reptext);
+ $$ = $1;
+ }
+ ;
+istart : ITEMIZE { $$ = lastsym; }
+ ;
+descrip : dstart LBRACK {
+ dprintf("\\begin{%s}\n",$1->s_reptext);
+ $$ = $1;
+ }
+ ;
+dstart : DESCRIPT { $$ = lastsym; }
+ ;
+env_itemize: ENV_ITEMIZE {
+ dprintf("\\begin{%s}\n",
+ lastsym->s_reptext);
+ }
+ ;
+env_descrip: ENV_DESCRIP {
+ dprintf("\\begin{%s}\n",
+ lastsym->s_reptext);
+ }
+ ;
+optnl : '\n'
+ | optnl BLANKLINE
+ |
+ ;
+items : items blanklines item
+ | item
+ ;
+item : item newline
+ | item line
+ | item ignore
+ | item env
+ | itemstrt
+ ;
+itemstrt: { dprintf("\\item "); dquote=0; }
+ ;
+
+/* these productions describe the list of items for an @description environment.
+ * The list is a bunch of items separated by one or more blank lines. There
+ * may also be interspersed keywords like "@index()" which we try to ignore
+ * and interspersed environments which couldn't be part of a tag.
+ */
+ditems : ditems blanklines ditem
+ | ditem
+ ;
+/* A single description item consists of stuff that we ignore, a first line
+ * that we search for a tag & other lines. Or it may consist entirely of
+ * stuff we ignore.
+ */
+ditem : dignores dfirstl lines
+ | dignores
+ | error '\n' { flushout("\\item[] "); }
+ ;
+dignores: dignores ignore newline
+ | dignores ignore
+ | dignores env newline
+ | dignores env
+ |
+ ;
+dfirstl : ditemstrt line TAB {
+ flushout("\\item[");
+ dprintf("] ");
+ }
+ | ditemstrt line '\n' {
+ flushout("\\item[] ");
+ dprintf("\n");
+ }
+ ;
+lines : lines newline
+ | lines linepart
+ | lines ignore
+ | lines env
+ |
+ ;
+
+/* we think we have the start of an item - delay output until we know
+ * whether or not to put a "\item[" in front of it
+ */
+ditemstrt: { delayout=1; dquote=0; }
+ ;
+
+line : line linepart
+ | line env
+ | line ignore
+ | linepart
+ ;
+linepart: control
+ | special
+ | char
+ ;
+supsub : SUP { dprintf("$^{\\hbox"); }
+ | SUB { dprintf("$_{\\hbox"); }
+ ;
+font : FONT LBRACK { dprintf("{\\%s ", lastsym->s_reptext); }
+ ;
+balbrack: lbrack sdoc rbrack
+ | lbrack rbrack
+ ;
+lbrack : LBRACK { dprintf("{"); }
+ ;
+rbrack : RBRACK { dprintf("}"); }
+ ;
+special : POINT { dprintf(".~"); }
+ | NPSPACE { dprintf("\\ "); }
+ | LBREAK { dprintf("\\newline{}"); }
+ | STILDE { dprintf("%%"); }
+ | HYPHEN { dprintf("\\-"); }
+ | COMMAND { dprintf("\\%s",&yytext[1]); }
+ ;
+text : text char
+ | char
+ | newline
+ | BLANKLINE { dprintf(incomment?"\n%% ":"\n"); dquote=0; }
+ | TAB { dprintf(" & "); }
+ | CENTER { dprintf(" & "); }
+ | RJUST { dprintf(" & "); }
+ | SETTAB { dprintf(" & "); }
+ ;
+char : CHAR { dprintf(yytext); }
+ | '@' { dprintf("j"); }
+ | INCHES { dprintf("in"); }
+ | '{' { dprintf("\\{"); }
+ | '}' { dprintf("\\}"); }
+ | '#' { dprintf("\\#"); }
+ | '$' { dprintf("\\$"); }
+ | '%' { dprintf("\\%%"); }
+ | '&' { dprintf("\\&"); }
+ | '~' { dprintf("{\\tt\\char`\\~}"); }
+ | '_' { dprintf("{\\tt\\char`\\_}"); }
+ | '^' { dprintf("{\\tt\\char`\\^}"); }
+ | '\\' { dprintf("{\\tt\\char`\\\\}"); }
+ | '<' { dprintf("{\\tt\\char`\\<}"); }
+ | '>' { dprintf("{\\tt\\char`\\>}"); }
+ | '|' { dprintf("{\\tt\\char`\\|}"); }
+ | '"' { if( dirquote ) {
+ dprintf( dquote? "'":"`");
+ dquote=!dquote;
+ } else
+ dprintf("{\\tt\\char`\\\"}");
+ }
+ ;
+newline : '\n' {
+ if ( incomment )
+ dprintf("\n%% ");
+ else
+ dprintf(informat?"\\\\\n":"\n");
+ }
+ ;
+blanklines: blanklines BLANKLINE
+ | BLANKLINE { dprintf(incomment?"\n%% ":"\n"); dquote=0; }
+ ;
+%%
+
+main( argc, argv )
+char **argv; {
+ char *pname = *argv;
+ init_st();
+ argc--, argv++;
+ while( argc > 0 && argv[0][0] == '-' ) {
+ if ( strcmp(*argv, "-s")==0 ) {
+ if ( argc < 1 ) {
+ fprintf( stderr,
+ "%s: filename must follow -s\n",
+ pname );
+ exit(1);
+ }
+ argv++;
+ argc--;
+ read_st( *argv );
+ } else {
+ if( index( *argv, 'k' ) )
+ kflag++;
+ if( index( *argv, 'q' ) )
+ dirquote = 0;
+ }
+ argv++;
+ argc--;
+ }
+ if ( argc > 0 )
+ while ( argc-- > 0 ) {
+ if ( freopen( *argv, "r", stdin ) == NULL ) {
+ perror( *argv );
+ exit(1);
+ }
+ inputfile = *argv;
+ inputline = 1;
+ yyparse();
+ argv++;
+ }
+ else {
+ inputfile = "<stdin>";
+ yyparse();
+ }
+}
+
+yyerror( str )
+char *str; {
+ fprintf( stderr,
+ "s2l: %s in %s line %d\n", str, inputfile, inputline );
+}
+
+/* initialize the keyword symbol table */
+init_st() {
+
+ /* straight keyword replacement */
+ enter("@begin", KW_REP, "begin");
+ enter("@end", KW_REP, "end");
+ enter("@unnumbered",KW_REP,"chapter*");
+ enter("@bigsection",KW_REP,"chapter");
+ enter("@blankspace",KW_REP,"vspace");
+ enter("@ux",KW_REP,"underline");
+
+ /* keywords to turn into environments */
+ enter("@example",KW_ENV,"example");
+ enter("@center",KW_ENV,"center");
+
+ /* keywords that behave like fonts (eg, @i{} -> {\it } */
+ enter("@i",FONT,"it");
+ enter("@u",FONT,"it");
+ enter("@un",FONT,"it");
+ enter("@b",FONT,"bf");
+ enter("@p",FONT,"bf");
+ enter("@t",FONT,"tt");
+ enter("@c",FONT,"sc");
+ enter("@r",FONT,"rm");
+ enter("@w",FONT,"obeyspaces");
+
+ /* list environments */
+ enter("@itemize",ITEMIZE,"itemize");
+ enter("@enumerate",ITEMIZE,"enumerate");
+ enter("@description",DESCRIPT,"description");
+ enter("@multiple",KW_DEL,"");
+
+ /* the begin-end form of list environments */
+ enter("itemize",ENV_ITEMIZE,"itemize");
+ enter("enumerate",ENV_ITEMIZE,"enumerate");
+ enter("description",ENV_DESCRIP,"description");
+ enter("multiple",ENV_DEL,"");
+
+ /* environments to be renamed */
+ enter("@format",KW_FORMAT,"tabular");
+ enter("format",ENV_FORMAT,"tabular");
+
+ /* comments */
+ enter("@comment",KW_COM,"comment");
+ enter("comment",ENV_COM,"comment");
+
+ /* keywords to "ignore" in description env */
+ enter("@tabs",KW_IGN,"tabs");
+ enter("@index",KW_IGN,"index");
+}
+
+/* Read User-specified entries into the symbol table */
+
+#define ENTER(txt,typ,rtxt) enter(txt,*txt=='@'?typ,rtxt)
+
+read_st( fname )
+char *fname;
+{
+ FILE *stream;
+ char text[128], stype[128], reptext[128];
+ register int sstat;
+
+ if ( (stream = fopen( fname, "r" )) == NULL ) {
+ perror( stream );
+ exit(1);
+ }
+
+ while ( (sstat = fscanf( stream, "%s %s %s \n", text, stype, reptext ))
+ != EOF ) {
+
+ if ( sstat == 3 ) {
+ switch( stype[0] ) {
+
+ case 'R': case 'r':
+ ENTER( text, KW_REP:ENV_REP, reptext );
+ break;
+ case 'D': case 'd':
+ ENTER( text, KW_DEL:ENV_DEL, reptext );
+ break;
+ case 'F': case 'f':
+ enter( text, FONT, reptext );
+ break;
+ case 'E': case 'e':
+ ENTER( text, KW_ENV:ENV_KW, reptext );
+ break;
+ case 'I': case 'i': case 'L': case 'l':
+ ENTER( text, ITEMIZE:ENV_ITEMIZE, reptext );
+ break;
+ case 'T': case 't':
+ ENTER( text, DESCRIPT:ENV_DESCRIP, reptext );
+ break;
+ case 'A': case 'a':
+ ENTER( text, KW_FORMAT:ENV_FORMAT, reptext );
+ break;
+ case 'N': case 'n':
+ enter( text, KW_IGN, reptext );
+ break;
+ case 'C': case 'c':
+ ENTER( text, KW_COM:ENV_COM, reptext );
+ break;
+ default:
+ fprintf(stderr,"-unknown type `%s'\n",stype);
+ exit(1);
+ }
+ }
+ }
+ fclose( stream );
+}
+
+/* dprintf - a (possibly delayed) printf
+ * This routine is used for all Latex output. If the flag "delayout"
+ * isn't set, it's just a printf. If delayout is set, an sprintf is done
+ * & the text is accumulated in a local buffer. The buffer is written out
+ * when by a call to flushout. This routine is intended to handle cases
+ * where yoyoy don't know what text to generate until several tokens later
+ * in the input. In particular, for an "@description" item yoy don't know
+ * whether to put an "\item[" at the beginning of the line until yoy see a
+ * tab or newline. Because this routine uses a static buffer, it will
+ * screw up on things like a description environment inside of a
+ * description tag (which I can't imagine happening). The static buffer
+ * is also finite so yoy can't delay a very large portion of the document.
+ */
+static char delbuf[DELBUFLEN]; /* buffer for delayed text */
+static int delcnt = 0; /* count of characters in delbuf */
+
+dprintf( fmt, a1, a2, a3, a4 )
+char *fmt;
+{
+ if( delayout ) {
+ /* we're delaying output text */
+ sprintf( &delbuf[delcnt], fmt, a1, a2, a3, a4 );
+ delcnt = strlen( delbuf );
+ if( delcnt >= (DELBUFLEN-50) ) {
+ yyerror( "delayed text buffer overflow" );
+ exit(1);
+ }
+ } else {
+ printf( fmt, a1, a2, a3, a4 );
+ }
+}
+
+/* flush the delayed output buffer, inserting the string "prefix"
+ * just after the last newline in the buffer.
+ */
+flushout( prefix )
+char *prefix;
+{
+ char *nlpos;
+
+ if( delayout ) {
+ if( nlpos = rindex( delbuf, '\n' ) ) {
+ *nlpos = '\0';
+ printf( "%s", delbuf );
+ nlpos++;
+ printf( "\n%s%s", prefix, nlpos );
+ } else {
+ printf( "%s%s", prefix, delbuf );
+ }
+ delcnt = 0;
+ delayout = 0;
+ }
+}
+
+#include "lex.yy.c"
diff --git a/support/s2latex/s2latex.patch b/support/s2latex/s2latex.patch
new file mode 100644
index 0000000000..e9111bfb7f
--- /dev/null
+++ b/support/s2latex/s2latex.patch
@@ -0,0 +1,95 @@
+The following are patches against the standard s2latex distribution (at
+least as of April 1996, but it doesn't look like it's going to be changing
+any time in the near future). They port s2latex to ANSI C (allowing it to
+compile and link correctly under all modern C compilers), as well as clean
+up the Makefile, fix make clean, and add a make distclean target.
+
+To apply these patches, use:
+
+ patch < s2latex.patch
+
+If you don't have patch on your system, you can obtain it from
+prep.ai.mit.edu (or any mirror) in /pub/gnu; I highly recommend you
+install it. Alternately, you can just make the below changes by hand
+(there aren't very many).
+
+Feel free to send me any corrections or additions to these patches, but be
+aware that I only compile s2latex; I don't actually use it. I therefore
+am not a good person to send general s2latex questions to.
+
+ Russ Allbery
+ rra@cs.stanford.edu
+
+--------------------------------------------------------------------------
+
+--- Makefile.orig Sun Aug 5 17:00:00 1990
++++ Makefile Sat Apr 6 17:29:11 1996
+@@ -1,12 +1,12 @@
+-CFLAGS=-O
++CFLAGS=-O2
+
+ all: s2latex s2latex.1
+
+ s2latex: y.tab.c lex.yy.c symtab.o symtab.h
+- cc ${CFLAGS} -o s2latex y.tab.c symtab.o -ll
++ $(CC) ${CFLAGS} -o s2latex y.tab.c symtab.o -ll
+
+ y.tab.c: s2l.y
+- yacc s2l.y
++ $(YACC) s2l.y
+
+ lex.yy.c: s2l.l
+ lex s2l.l
+@@ -15,7 +15,10 @@
+ tbl s2latex.tbl >s2latex.1
+
+ clean:
+- rm -f y.tab.c lex.yy.c core y.tab.h *.o s2latex.1
++ rm -f y.tab.c lex.yy.c core y.tab.h *.o s2latex
++
++distclean: clean
++ rm -f s2latex.1
+
+ mktar:
+ tar cvf s2latex.tar Makefile s2l.y s2l.l symtab.c symtab.h s2latex.tbl
+--- s2l.y.orig Sun Oct 7 17:00:00 1990
++++ s2l.y Sat Apr 6 17:28:08 1996
+@@ -38,7 +38,7 @@
+
+ #include <stdio.h>
+ #include <ctype.h>
+-#include <strings.h>
++#include <string.h>
+ #include "symtab.h"
+
+ #define DELBUFLEN 1024 /* "delayed" text buffer length (see comments
+@@ -317,7 +317,7 @@
+ | '<' { dprintf("{\\tt\\char`\\<}"); }
+ | '>' { dprintf("{\\tt\\char`\\>}"); }
+ | '|' { dprintf("{\\tt\\char`\\|}"); }
+- | '"' { if( dirquote ) {
++ | '\"' { if( dirquote ) {
+ dprintf( dquote? "'":"`");
+ dquote=!dquote;
+ } else
+@@ -353,9 +353,9 @@
+ argc--;
+ read_st( *argv );
+ } else {
+- if( index( *argv, 'k' ) )
++ if( strchr( *argv, 'k' ) )
+ kflag++;
+- if( index( *argv, 'q' ) )
++ if( strchr( *argv, 'q' ) )
+ dirquote = 0;
+ }
+ argv++;
+@@ -534,7 +534,7 @@
+ char *nlpos;
+
+ if( delayout ) {
+- if( nlpos = rindex( delbuf, '\n' ) ) {
++ if( nlpos = strrchr( delbuf, '\n' ) ) {
+ *nlpos = '\0';
+ printf( "%s", delbuf );
+ nlpos++;
diff --git a/support/s2latex/s2latex.tbl b/support/s2latex/s2latex.tbl
new file mode 100644
index 0000000000..39455f45aa
--- /dev/null
+++ b/support/s2latex/s2latex.tbl
@@ -0,0 +1,209 @@
+.TH S2LATEX 1-local
+.SH NAME
+s2latex \- convert Scribe input files to TeX/Latex input files
+.SH SYNOPSIS
+.B s2latex
+[
+.B \-k
+] [
+.B \-q
+] [
+.B \-s
+symfile
+]
+file ...
+.br
+.SH DESCRIPTION
+.B S2latex
+reads the
+.I files
+and produces a
+.I Latex
+input file on the standard output. If no files are given, s2latex reads
+standard input.
+.TP
+.B -k
+outputs every unrecognized Scribe keyword to stderr.
+Default translation rules are applied to unrecognized keywords (i.e.,
+.I @keyword(...) \(-> \ekeyword{...}
+and
+.I @begin(env) \(-> \ebegin{env}).
+This option can be used to call your attention to keywords that should
+use other translation rules.
+.TP
+.B -q
+changes the processing of double quotes. Normally, double quotes are
+converted to directed single quotes (i.e., "..." \(-> `...'). This
+flag leaves the double quotes (they are printed from the "tt" font).
+.TP
+.B -s
+gives the name of a file containing additional or replacement
+translation rules for Scribe keywords or environments.
+Each line of this file should have the format:
+
+.I
+ word rule replacement
+
+.I word
+is the keyword or environment name (a keyword name is distinguished
+by a leading "@"). This name should be given in
+.B "lower case" .
+.I Rule
+is the name of the translation rule (see below). It can be in either case
+and only the first character is significant.
+.I Replacement
+is replacement text for the keyword. It
+must be given even if not required by the rule.
+.PP
+.B S2latex
+has 9 translation rules (read "\(->" as "is converted to"):
+.TP
+replace:
+.I @kw(...) \(-> \erep{...}
+.br
+.I @begin(env)...@end(env) \(-> \ebegin{rep}...\eend{rep}
+.br
+I.e., the keyword or environment
+name is simply replaced by a new name.
+.TP
+delete:
+.I @kw(...) \(-> ...
+.br
+.I @begin(env)...@end(env) \(-> ...
+.br
+I.e., the keyword or environment is deleted but the enclosed
+text is left.
+.TP
+font:
+.I @kw(...) \(-> {\erep ...}
+.br
+.I @begin(env)...@end(env) \(-> {\erep ...}
+.br
+This is the appropriate translation for
+a TeX font; i.e., @i(xyz) to {\eit xyz}.
+.TP
+environment:
+.I @kw(...) \(-> \ebegin{rep}...\eend{rep}
+.br
+.I @begin(env)...@end(env) \(-> \erep{...}
+.br
+I.e., a keyword is converted
+to an environment or an environment to a keyword.
+.TP
+itemize:
+.I @kw(...) \(-> \ebegin{rep}...\eend{rep}
+.br
+.I @begin(env)...@end(env) \(-> \ebegin{rep}...\eend{rep}
+.br
+In addition, the start of each new paragraph in the enclosed text
+will be preceded by a "\eitem\ ".
+.TP
+tag:
+(aka, "description"). Like
+.I itemize
+but the start of each new paragraph is preceded by "\eitem[" and
+the first tab in the paragraph is replaced by "]\ ". I.e., this is
+the Latex "description" environment.
+.TP
+comment:
+The keyword or environment and all of the text enclosed are output
+preceded by "%" (the TeX comment character). I.e., this "comments
+out" a keyword or environment.
+.TP
+alignment:
+.I @kw(...) \(-> \ebegin{rep}...\eend{rep}
+.I @begin(env)...@end(env) \(-> \ebegin{rep}...\eend{rep}
+.br
+Each Scribe tab in the enclosed text is replaced with "\ &\ " (the TeX
+alignment tab) and each newline is preceded by "\e\e".
+.TP
+nop:
+.I @kw(...) \(-> \erep{...}
+.br
+Like
+.I replace
+but has the side effect of saying this keyword generates no text. (This
+is used when s2latex is trying to identify the "tag" portion of a paragraph
+in a @description environment).
+.PP
+.B S2latex
+starts with the following translation rules. The user can augment
+or redefine any of these rules via the
+.B '-s'
+command line option.
+.sp
+.TS
+center;
+l1p8 l1p8 l1p8.
+@unnumbered REPLACE chapter*
+@bigsection REPLACE chapter
+@blankspace REPLACE vspace
+@ux REPLACE underline
+@example ENV example
+@center ENV center
+@i FONT it
+@u FONT it
+@un FONT it
+@b FONT bf
+@p FONT bf
+@t FONT tt
+@c FONT sc
+@r FONT rm
+@w FONT obeyspaces
+@itemize ITEMIZE itemize
+itemize ITEMIZE itemize
+@enumerate ITEMIZE enumerate
+enumerate ITEMIZE enumerate
+@description TAG description
+description TAG description
+@multiple DELETE -
+multiple DELETE -
+@format ALIGN tabular
+format ALIGN tabular
+@comment COMMENT comment
+comment COMMENT comment
+@index NOP index
+@tabs NOP tabs
+.TE
+.SH "SEE ALSO"
+tex(1), latex(1)
+.SH AUTHOR
+Van Jacobson, Lawrence Berkeley Laboratory (van@lbl-csam.arpa) with thanks
+to Richard Furuta for much help decoding Scribe.
+.SH BUGS
+.PP
+The program isn't intended to do a 100% conversion. It usually
+gets about 90% right on the first pass. With the addition of a
+few translation rules & some judicious editting of the Scribe input
+file, it can get you 99% of the way to a document that Latex will
+accept. This may still be a long way from a document that you'll
+accept but such are the joys of typesetting.
+.PP
+The "parse error at line xxx" message isn't all that helpful. Start by
+looking in the input file around the line number given.
+Errors are usually caused by:
+.IP \(bu 2n
+a Scribe macro or environment definition.
+Delete it from the input file & try again.
+.IP \(bu 2n
+some interesting new way to do "descriptions" or "formats". If it's
+a description, either fix things so s2latex can find the tag or
+put in a dummy tag so that the rest of the description environment
+doesn't get screwed up. If it's a format, either the fixup will be
+obvious or you should change to format keyword to something
+unrecognized & fix things later in the output file.
+.PP
+The following two character control sequences probably
+should be converted to something but aren't:
+@!, @$, @:, @/, @|, @&, @), @# and @].
+.PP
+In a format environment, all Scribe tab commands
+(@\e, @=, @>, @^) get converted to
+the TeX alignment tab (&).
+.PP
+A lot better job could be done on formats and macro
+definitions.
+
+
+
+
diff --git a/support/s2latex/symtab.c b/support/s2latex/symtab.c
new file mode 100644
index 0000000000..63fd9f9a90
--- /dev/null
+++ b/support/s2latex/symtab.c
@@ -0,0 +1,76 @@
+/* symtab.c 1.2 85/02/04 */
+/* symbol table routines for scribe-to-latex
+ *
+ * copyright (c) 1984 by Van Jacobson, Lawrence Berkeley Laboratory
+ * This program may be freely redistributed but not for profit. This
+ * comment must remain in the program or any derivative.
+ */
+
+#include <ctype.h>
+#include "symtab.h"
+
+#define HASHSIZE 127
+#define MAXSYM 128 /* max char in a symbol name */
+
+static struct stab *sthash[HASHSIZE];
+
+#define SYMHASH(str) ((str[0]+(str[1]<<8))%HASHSIZE)
+
+
+struct stab *lookup( str )
+ register char *str;
+{
+ register struct stab *s;
+ char text[MAXSYM];
+ register char *cp = text;
+ register char *textend = &text[MAXSYM-1];
+
+ /* convert the string to lower case, then try to find it */
+ while( *str && cp<textend )
+ *cp++ = (isupper(*str)? tolower(*str++): *str++);
+
+ *cp = '\0';
+
+ s = sthash[SYMHASH(text)];
+ while( s && strcmp(text,s->s_text) )
+ s = s->s_next;
+
+ return(s);
+}
+
+struct stab *enter( text, type, reptext )
+ char *text, *reptext;
+ int type;
+{
+ register struct stab *n;
+
+ /* set up the new entry */
+
+ n = (struct stab *) malloc( sizeof(struct stab) );
+ n->s_text = (char *) malloc( strlen(text)+1 );
+ lc_strcpy( n->s_text, text );
+ n->s_reptext = (char *) malloc( strlen(reptext)+1 );
+ lc_strcpy( n->s_reptext, reptext );
+ n->s_type = type;
+
+ /* add it to the table */
+
+ n->s_next = sthash[SYMHASH(n->s_text)];
+ sthash[SYMHASH(n->s_text)] = n;
+ return(n);
+}
+
+/* copy a string converting upper case to lower case. */
+lc_strcpy( dst, src )
+char *dst;
+char *src;
+{
+ while( *src )
+ *dst++ = isupper(*src)? tolower(*src++): *src++;
+
+ *dst = '\0';
+}
+
+
+
+
diff --git a/support/s2latex/symtab.h b/support/s2latex/symtab.h
new file mode 100644
index 0000000000..c134e0c5ba
--- /dev/null
+++ b/support/s2latex/symtab.h
@@ -0,0 +1,15 @@
+/* symtab.h 1.1 85/02/04 */
+
+struct stab {
+ struct stab *s_next;
+ int s_type;
+ char *s_text;
+ char *s_reptext;
+};
+
+extern struct stab *lookup();
+extern struct stab *enter();
+
+
+
+
diff --git a/support/s2latex/win32/s2latex-win32.readme b/support/s2latex/win32/s2latex-win32.readme
new file mode 100644
index 0000000000..2567f1d4bd
--- /dev/null
+++ b/support/s2latex/win32/s2latex-win32.readme
@@ -0,0 +1,30 @@
+* scribe2latex-1.0 for Windows *
+================================
+
+What is it?
+-----------
+Scribe2LaTeX: convert Scribe input files to TeX/Latex input files
+
+Homepage
+--------
+ftp://ctan.tug.org/tex-archive/support/s2latex
+
+System
+------
+- Windows95/98/2000/NT with msvcrt.dll
+- if msvcrt.dll is not in your Windows/System folder, get it
+ from http://www.simtel.net/simtel.net/win95/dll
+ or by installing Internet Explorer 4.0 or higher
+
+Notes
+-----
+- see also scribe2latex.htm
+
+Package Availability
+--------------------
+- in: http://gnuwin32.sourceforge.net/
+- as: scribe2latex-1.0-bin.zip
+
+Documentation
+-------------
+- scribe2latex-1.0-doc.zip