/* tex2doc.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* Konverter TeX-->ASCII-DOC */ /* */ /* Historie: 9. 2.1998 Grundsteinlegung */ /* 20. 6.1998 Zentrierung */ /* 11. 7.1998 weitere Landessonderzeichen */ /* 13. 7.1998 Cedilla */ /* 12. 9.1998 input-Statement */ /* 12. 1.1999 andere Kapitelherarchie fuer article */ /* */ /*****************************************************************************/ #include "stdinc.h" #include "asmitree.h" #include "chardefs.h" #include #include #include "strutil.h" #include "findhyphen.h" #ifndef __MSDOS__ #include "ushyph.h" #include "grhyph.h" #endif /*--------------------------------------------------------------------------*/ #define TOKLEN 250 static char *TableName, *BiblioName, *ContentsName, #define ErrorEntryCnt 3 *ErrorEntryNames[ErrorEntryCnt]; typedef enum{EnvNone,EnvDocument,EnvItemize,EnvEnumerate,EnvDescription,EnvTable, EnvTabular,EnvRaggedLeft,EnvRaggedRight,EnvCenter,EnvVerbatim, EnvQuote,EnvTabbing,EnvBiblio,EnvMarginPar,EnvCaption,EnvHeading,EnvCount} EnvType; typedef enum{FontStandard,FontEmphasized,FontBold,FontTeletype,FontItalic} TFontType; typedef enum{FontTiny,FontSmall,FontNormalSize,FontLarge,FontHuge} TFontSize; typedef enum{AlignNone,AlignCenter,AlignLeft,AlignRight} TAlignment; typedef struct _TEnvSave { struct _TEnvSave *Next; EnvType SaveEnv; int ListDepth,ActLeftMargin,LeftMargin,RightMargin; int EnumCounter,FontNest; TAlignment Alignment; } TEnvSave,*PEnvSave; typedef struct _TFontSave { struct _TFontSave *Next; TFontType FontType; TFontSize FontSize; } TFontSave,*PFontSave; typedef enum{ColLeft,ColRight,ColCenter,ColBar} TColumn; #define MAXCOLS 30 #define MAXROWS 200 typedef char *TableLine[MAXCOLS]; typedef struct { int ColumnCount,TColumnCount; TColumn ColTypes[MAXCOLS]; int ColLens[MAXCOLS]; int LineCnt; TableLine Lines[MAXROWS]; Boolean LineFlags[MAXROWS]; Boolean MultiFlags[MAXROWS]; } TTable; typedef struct _TRefSave { struct _TRefSave *Next; char *RefName,*Value; } TRefSave,*PRefSave; typedef struct _TTocSave { struct _TTocSave *Next; char *TocName; } TTocSave,*PTocSave; static char *EnvNames[EnvCount]= {"___NONE___","document","itemize","enumerate","description","table","tabular", "raggedleft","raggedright","center","verbatim","quote","tabbing", "thebibliography","___MARGINPAR___","___CAPTION___","___HEADING___"}; static int IncludeNest; static FILE *infiles[50],*outfile; static char *infilename; static char TocName[200]; static int CurrLine=0,CurrColumn; #define CHAPMAX 6 static int Chapters[CHAPMAX]; static int TableNum,FontNest,ErrState,FracState,BibIndent,BibCounter; #define TABMAX 100 static int TabStops[TABMAX],TabStopCnt,CurrTabStop; static Boolean InAppendix,InMathMode,DoRepass; static TTable ThisTable; static int CurrRow,CurrCol; static Boolean GermanMode; static EnvType CurrEnv; static TFontType CurrFontType; static TFontSize CurrFontSize; static int CurrListDepth; static int EnumCounter; static int ActLeftMargin,LeftMargin,RightMargin; static TAlignment Alignment; static PEnvSave EnvStack; static PFontSave FontStack; static PRefSave FirstRefSave,FirstCiteSave; static PTocSave FirstTocSave; static PInstTable TeXTable; /*--------------------------------------------------------------------------*/ void ChkStack(void) BEGIN END static void error(char *Msg) BEGIN int z; fprintf(stderr,"%s:%d.%d: %s\n",infilename,CurrLine,CurrColumn,Msg); for (z=0; zNext) if ((cmp=strcmp(Run->RefName,Name))>=0) break; if ((Run!=Nil) AND (cmp==0)) BEGIN if (strcmp(Run->Value,Value)!=0) BEGIN sprintf(err,"value of label '%s' has changed",Name); warning(err); DoRepass=True; free(Run->Value); Run->Value=strdup(Value); END END else BEGIN Neu=(PRefSave) malloc(sizeof(TRefSave)); Neu->RefName=strdup(Name); Neu->Value=strdup(Value); Neu->Next=Run; if (Prev==Nil) FirstRefSave=Neu; else Prev->Next=Neu; END END static void AddCite(char *Name, char *Value) BEGIN PRefSave Run,Prev,Neu; int cmp=(-1); char err[200]; for (Run=FirstCiteSave,Prev=Nil; Run!=Nil; Prev=Run,Run=Run->Next) if ((cmp=strcmp(Run->RefName,Name))>=0) break; if ((Run!=Nil) AND (cmp==0)) BEGIN if (strcmp(Run->Value,Value)!=0) BEGIN sprintf(err,"value of citation '%s' has changed",Name); warning(err); DoRepass=True; free(Run->Value); Run->Value=strdup(Value); END END else BEGIN Neu=(PRefSave) malloc(sizeof(TRefSave)); Neu->RefName=strdup(Name); Neu->Value=strdup(Value); Neu->Next=Run; if (Prev==Nil) FirstCiteSave=Neu; else Prev->Next=Neu; END END static void GetLabel(char *Name, char *Dest) BEGIN PRefSave Run; char err[200]; for (Run=FirstRefSave; Run!=Nil; Run=Run->Next) if (strcmp(Name,Run->RefName)==0) break; if (Run==Nil) BEGIN sprintf(err,"undefined label '%s'",Name); warning(err); DoRepass=True; END strcpy(Dest,(Run==Nil) ? "???" : Run->Value); END static void GetCite(char *Name, char *Dest) BEGIN PRefSave Run; char err[200]; for (Run=FirstCiteSave; Run!=Nil; Run=Run->Next) if (strcmp(Name,Run->RefName)==0) break; if (Run==Nil) BEGIN sprintf(err,"undefined citation '%s'",Name); warning(err); DoRepass=True; END strcpy(Dest,(Run==Nil) ? "???" : Run->Value); END static void PrintLabels(char *Name) BEGIN PRefSave Run; FILE *file=fopen(Name,"a"); if (file==Nil) perror(Name); for (Run=FirstRefSave; Run!=Nil; Run=Run->Next) fprintf(file,"Label %s %s\n",Run->RefName,Run->Value); fclose(file); END static void PrintCites(char *Name) BEGIN PRefSave Run; FILE *file=fopen(Name,"a"); if (file==Nil) perror(Name); for (Run=FirstCiteSave; Run!=Nil; Run=Run->Next) fprintf(file,"Citation %s %s\n",Run->RefName,Run->Value); fclose(file); END static void PrintToc(char *Name) BEGIN PTocSave Run; FILE *file=fopen(Name,"w"); if (file==Nil) perror(Name); for (Run=FirstTocSave; Run!=Nil; Run=Run->Next) fprintf(file,"%s\n\n",Run->TocName); fclose(file); END /*------------------------------------------------------------------------------*/ static void GetNext(char *Src, char *Dest) BEGIN char *c=strchr(Src,' '); if (c==Nil) BEGIN strcpy(Dest,Src); *Src='\0'; END else BEGIN *c='\0'; strcpy(Dest,Src); for (c++; *c==' '; c++); strcpy(Src,c); END END static void ReadAuxFile(char *Name) BEGIN FILE *file=fopen(Name,"r"); char Line[300],Cmd[300],Nam[300],Val[300]; if (file==Nil) return; while (NOT feof(file)) BEGIN if (fgets(Line,299,file)==Nil) break; if (Line[strlen(Line)-1]=='\n') Line[strlen(Line)-1]='\0'; GetNext(Line,Cmd); if (strcmp(Cmd,"Label")==0) BEGIN GetNext(Line,Nam); GetNext(Line,Val); AddLabel(Nam,Val); END else if (strcmp(Cmd,"Citation")==0) BEGIN GetNext(Line,Nam); GetNext(Line,Val); AddCite(Nam,Val); END END fclose(file); END /*--------------------------------------------------------------------------*/ static Boolean issep(char inp) BEGIN return ((inp==' ') OR (inp=='\t') OR (inp=='\n')); END static Boolean isalphanum(char inp) BEGIN return ((inp>='A') AND (inp<='Z')) OR ((inp>='a') AND (inp<='z')) OR ((inp>='0') AND (inp<='9')) OR (inp=='.'); END static char LastChar='\0'; static char SaveSep='\0',SepString[TOKLEN]=""; static Boolean DidEOF=False; static char BufferLine[TOKLEN]="",*BufferPtr=BufferLine; typedef struct { char Token[TOKLEN],Sep[TOKLEN]; } PushedToken; static int PushedTokenCnt=0; static PushedToken PushedTokens[16]; static int GetChar(void) BEGIN Boolean Comment; static Boolean DidPar=False; char *Result; if (*BufferPtr=='\0') BEGIN do BEGIN if (IncludeNest<=0) return EOF; do BEGIN Result=fgets(BufferLine,TOKLEN,infiles[IncludeNest-1]); if (Result!=Nil) break; fclose(infiles[--IncludeNest]); if (IncludeNest<=0) return EOF; END while (True); CurrLine++; BufferPtr=BufferLine; Comment=(strlen(BufferLine)>=2) AND (strncmp(BufferLine,"%%",2)==0); if ((*BufferLine=='\0') OR (*BufferLine=='\n')) BEGIN if ((CurrEnv==EnvDocument) AND (NOT DidPar)) BEGIN strcpy(BufferLine,"\\par\n"); DidPar=True; Comment=False; END END else if (NOT Comment) DidPar=False; END while (Comment); END return *(BufferPtr++); END static Boolean ReadToken(char *Dest) BEGIN int ch,z; Boolean Good; char *run; if (PushedTokenCnt>0) BEGIN strcpy(Dest,PushedTokens[0].Token); strcpy(SepString,PushedTokens[0].Sep); for (z=0; z=16) return; strcpy(PushedTokens[PushedTokenCnt].Token,Token); strcpy(PushedTokens[PushedTokenCnt].Sep,SepString); PushedTokenCnt++; END /*--------------------------------------------------------------------------*/ static void assert_token(char *ref) BEGIN char token[TOKLEN]; ReadToken(token); if (strcmp(ref,token)!=0) BEGIN sprintf(token,"\"%s\" expected",ref); error(token); END END static void collect_token(char *dest, char *term) BEGIN char Comp[TOKLEN]; Boolean first=TRUE,done; *dest='\0'; do BEGIN ReadToken(Comp); done=(strcmp(Comp,term)==0); if (NOT done) BEGIN if (NOT first) strcat(dest,SepString); strcat(dest,Comp); END first=False; END while (NOT done); END /*--------------------------------------------------------------------------*/ static char OutLineBuffer[TOKLEN]="",SideMargin[TOKLEN]; static void PutLine(Boolean DoBlock) BEGIN int ll=RightMargin-LeftMargin+1; int l,n,ptrcnt,diff,div,mod,divmod; char *chz,*ptrs[50]; Boolean SkipFirst,IsFirst; fputs(Blanks(LeftMargin-1),outfile); if ((Alignment!=AlignNone) OR (NOT DoBlock)) BEGIN l=strlen(OutLineBuffer); diff=ll-l; switch (Alignment) BEGIN case AlignRight: fputs(Blanks(diff),outfile); l=ll; break; case AlignCenter: fputs(Blanks(diff>>1),outfile); l+=diff>>1; break; default: break; END fputs(OutLineBuffer,outfile); END else BEGIN SkipFirst=((CurrEnv==EnvItemize) OR (CurrEnv==EnvEnumerate) OR (CurrEnv==EnvDescription) OR (CurrEnv==EnvBiblio)); if (LeftMargin==ActLeftMargin) SkipFirst=False; l=ptrcnt=0; IsFirst=SkipFirst; for (chz=OutLineBuffer; *chz!='\0'; chz++) BEGIN if ((chz>OutLineBuffer) AND (*(chz-1)!=' ') AND (*chz==' ')) BEGIN if (NOT IsFirst) ptrs[ptrcnt++]=chz; IsFirst=False; END l++; END diff=ll+1-l; div=(ptrcnt>0) ? diff/ptrcnt : 0; mod=diff-(ptrcnt*div); divmod=(mod>0) ? ptrcnt/mod : ptrcnt+1; IsFirst=SkipFirst; ptrcnt=0; for (chz=OutLineBuffer; *chz!='\0'; chz++) BEGIN fputc(*chz,outfile); if ((chz>OutLineBuffer) AND (*(chz-1)!=' ') AND (*chz==' ')) BEGIN if (NOT IsFirst) BEGIN n=div; if ((mod>0) AND ((ptrcnt%divmod)==0)) BEGIN mod--; n++; END if (n>0) fputs(Blanks(n),outfile); ptrcnt++; END IsFirst=False; END END l=RightMargin-LeftMargin+1; END if (*SideMargin!='\0') BEGIN fputs(Blanks(ll+3-l),outfile); fprintf(outfile,"%s",SideMargin); *SideMargin='\0'; END fputc('\n',outfile); LeftMargin=ActLeftMargin; END static void AddLine(char *Part, char *Sep) BEGIN int mlen=RightMargin-LeftMargin+1,*hyppos,hypcnt,z,hlen; char *search,save,*lastalpha; if (strlen(Sep)>1) Sep[1]='\0'; if (*OutLineBuffer!='\0') strcat(OutLineBuffer,Sep); strcat(OutLineBuffer,Part); if (strlen(OutLineBuffer)>=mlen) BEGIN search=OutLineBuffer+mlen; while (search>=OutLineBuffer) BEGIN if (*search==' ') break; if (search>OutLineBuffer) if (*(search-1)=='-') break; else if (*(search-1)=='/') break; else if (*(search-1)==';') break; else if (*(search-1)==';') break; search--; END if (search<=OutLineBuffer) BEGIN PutLine(True); *OutLineBuffer='\0'; END else BEGIN if (*search==' ') BEGIN for (lastalpha=search+1; *lastalpha!='\0'; lastalpha++) if ((mytolower(*lastalpha)<'a') OR (mytolower(*lastalpha)>'z')) break; if (lastalpha-search>3) BEGIN save=(*lastalpha); *lastalpha='\0'; DoHyphens(search+1,&hyppos,&hypcnt); *lastalpha=save; hlen=(-1); for (z=0; z0) BEGIN memmove(search+hlen+2,search+hlen+1,strlen(search+hlen+1)+1); search[hlen+1]='-'; search+=hlen+2; END if (hypcnt>0) free(hyppos); END END save=(*search); *search='\0'; PutLine(True); *search=save; for (; *search==' '; search++); strcpy(OutLineBuffer,search); END END END static void AddSideMargin(char *Part, char *Sep) BEGIN if (strlen(Sep)>1) Sep[1]='\0'; if (*Sep!='\0') if ((*SideMargin!='\0') OR (NOT issep(*Sep))) strcat(SideMargin,Sep); strcat(SideMargin,Part); END static void FlushLine(void) BEGIN if (*OutLineBuffer!='\0') BEGIN PutLine(False); *OutLineBuffer='\0'; END END static void ResetLine(void) BEGIN *OutLineBuffer='\0'; END /*--------------------------------------------------------------------------*/ static void SaveFont(void) BEGIN PFontSave NewSave; NewSave=(PFontSave) malloc(sizeof(TFontSave)); NewSave->Next=FontStack; NewSave->FontSize=CurrFontSize; NewSave->FontType=CurrFontType; FontStack=NewSave; FontNest++; END static void RestoreFont(void) BEGIN PFontSave OldSave; if (FontStack==Nil) return; OldSave=FontStack; FontStack=FontStack->Next; CurrFontSize=OldSave->FontSize; CurrFontType=OldSave->FontType; free(OldSave); FontNest--; END static void SaveEnv(EnvType NewEnv) BEGIN PEnvSave NewSave; NewSave=(PEnvSave) malloc(sizeof(TEnvSave)); NewSave->Next=EnvStack; NewSave->ListDepth=CurrListDepth; NewSave->LeftMargin=LeftMargin; NewSave->Alignment=Alignment; NewSave->ActLeftMargin=ActLeftMargin; NewSave->RightMargin=RightMargin; NewSave->EnumCounter=EnumCounter; NewSave->SaveEnv=CurrEnv; NewSave->FontNest=FontNest; EnvStack=NewSave; CurrEnv=NewEnv; FontNest=0; END static void RestoreEnv(void) BEGIN PEnvSave OldSave; OldSave=EnvStack; EnvStack=OldSave->Next; CurrListDepth=OldSave->ListDepth; LeftMargin=OldSave->LeftMargin; ActLeftMargin=OldSave->ActLeftMargin; RightMargin=OldSave->RightMargin; Alignment=OldSave->Alignment; EnumCounter=OldSave->EnumCounter; FontNest=OldSave->FontNest; CurrEnv=OldSave->SaveEnv; free(OldSave); END static void InitTableRow(int Index) BEGIN int z; for (z=0; z=ThisTable.TColumnCount)) error("too many columns within row"); CurrCol++; END static void AddTableEntry(char *Part, char *Sep) BEGIN char *Ptr=ThisTable.Lines[CurrRow][CurrCol]; int nlen=(Ptr==Nil) ? 0 : strlen(Ptr); Boolean UseSep=(nlen>0); if (strlen(Sep)>1) Sep[1]='\0'; if (UseSep) nlen+=strlen(Sep); nlen+=strlen(Part); if (Ptr==Nil) BEGIN Ptr=(char *) malloc(nlen+1); *Ptr='\0'; END else Ptr=(char *) realloc(Ptr,nlen+1); if (UseSep) strcat(Ptr,Sep); strcat(Ptr,Part); ThisTable.Lines[CurrRow][CurrCol]=Ptr; END static void DoPrnt(char *Ptr, TColumn Align, int len) BEGIN int l=(Ptr==Nil) ? 0 : strlen(Ptr),diff; len-=2; diff=len-l; fputc(' ',outfile); switch (Align) BEGIN case ColRight: fputs(Blanks(diff),outfile); break; case ColCenter: fputs(Blanks((diff+1)/2),outfile); break; default: break; END if (Ptr!=Nil) BEGIN fputs(Ptr,outfile); free(Ptr); END switch (Align) BEGIN case ColLeft: fputs(Blanks(diff),outfile); break; case ColCenter: fputs(Blanks(diff/2),outfile); break; default: break; END fputc(' ',outfile); END static void DumpTable(void) BEGIN int RowCnt,rowz,colz,colptr,ml,l,diff,sumlen,firsttext,indent; /* compute widths of individual rows */ /* get index of first text column */ RowCnt=(ThisTable.Lines[CurrRow][0]!=Nil) ? CurrRow+1 : CurrRow; firsttext=(-1); for (colz=colptr=0; colzsumlen) BEGIN diff=ml+4-sumlen; ThisTable.ColLens[firsttext]+=diff; END /* print rows */ for (rowz=0; rowz0) AND (Chapters[z]==0)) break; if ((InAppendix) AND (z==0)) run+=sprintf(run,"%c.",Chapters[z]+'A'); else run+=sprintf(run,"%d.",Chapters[z]); END return run; END /*--------------------------------------------------------------------------*/ static char BackSepString[TOKLEN]; static void TeXFlushLine(Word Index) BEGIN if (CurrEnv==EnvTabular) BEGIN for (CurrCol++; CurrCol=CHAPMAX) return; FlushLine(); fputc('\n',outfile); assert_token("{"); LastLevel=Level; SaveEnv(EnvHeading); RightMargin=200; Chapters[Level]++; for (z=Level+1; zNext=Nil; run=Line; run=GetSectionName(run); run+=sprintf(run," "); sprintf(run,"%s",Title); NewTocSave->TocName=(char *) malloc(6+Level+strlen(Line)); strcpy(NewTocSave->TocName,Blanks(5+Level)); strcat(NewTocSave->TocName,Line); if (FirstTocSave==Nil) FirstTocSave=NewTocSave; else BEGIN for (RunToc=FirstTocSave; RunToc->Next!=Nil; RunToc=RunToc->Next); RunToc->Next=NewTocSave; END END END static EnvType GetEnvType(char *Name) BEGIN EnvType z; for (z=EnvNone+1; z=MAXCOLS) error("too many columns in table"); if (strcmp(Add,"|")==0) NCol=ColBar; else if (strcmp(Add,"l")==0) NCol=ColLeft; else if (strcmp(Add,"r")==0) NCol=ColRight; else if (strcmp(Add,"c")==0) NCol=ColCenter; else BEGIN NCol=ColBar; error("unknown table column descriptor"); END if ((ThisTable.ColTypes[ThisTable.ColumnCount++]=NCol)!=ColBar) ThisTable.TColumnCount++; END END while (NOT done); InitTableRow(CurrRow=0); CurrCol=0; break; default: break; END END static void TeXEndEnv(Word Index) BEGIN char EnvName[TOKLEN],Add[TOKLEN]; EnvType NEnv; assert_token("{"); ReadToken(EnvName); if ((NEnv=GetEnvType(EnvName))==EnvTable) BEGIN ReadToken(Add); if (strcmp(Add,"*")==0) assert_token("}"); else if (strcmp(Add,"}")!=0) error("unknown table environment"); END else assert_token("}"); if (EnvStack==Nil) error("end without begin"); if (CurrEnv!=NEnv) error("begin and end of environment do not match"); switch (CurrEnv) BEGIN case EnvItemize: case EnvEnumerate: case EnvDescription: FlushLine(); if (CurrListDepth==1) fputc('\n',outfile); break; case EnvBiblio: case EnvQuote: case EnvTabbing: FlushLine(); fputc('\n',outfile); break; case EnvCenter: case EnvRaggedRight: case EnvRaggedLeft: FlushLine(); break; case EnvTabular: DumpTable(); break; case EnvTable: FlushLine(); fputc('\n',outfile); break; default: break; END RestoreEnv(); END static void TeXItem(Word Index) BEGIN char NumString[20],Token[TOKLEN],Acc[TOKLEN]; FlushLine(); switch(CurrEnv) BEGIN case EnvItemize: LeftMargin=ActLeftMargin-3; AddLine(" - ",""); break; case EnvEnumerate: LeftMargin=ActLeftMargin-4; sprintf(NumString,"%3d ",++EnumCounter); AddLine(NumString,""); break; case EnvDescription: ReadToken(Token); if (strcmp(Token,"[")!=0) BackToken(Token); else BEGIN collect_token(Acc,"]"); LeftMargin=ActLeftMargin-4; sprintf(NumString,"%3s ",Acc); AddLine(NumString,""); END break; default: error("\\item not in a list environment"); END END static void TeXBibItem(Word Index) BEGIN char NumString[20],Token[TOKLEN],Name[TOKLEN],Format[10]; if (CurrEnv!=EnvBiblio) error("\\bibitem not in bibliography environment"); assert_token("{"); collect_token(Name,"}"); FlushLine(); fputc('\n',outfile); ++BibCounter; LeftMargin=ActLeftMargin-BibIndent-3; sprintf(Format,"[%%%dd] ",BibIndent); sprintf(NumString,Format,BibCounter); AddLine(NumString,""); sprintf(NumString,"%d",BibCounter); AddCite(Name,NumString); ReadToken(Token); *SepString='\0'; BackToken(Token); END static void TeXAddDollar(Word Index) BEGIN DoAddNormal("$",BackSepString); END static void TeXAddUnderbar(Word Index) BEGIN DoAddNormal("_",BackSepString); END static void TeXAddPot(Word Index) BEGIN DoAddNormal("^",BackSepString); END static void TeXAddAmpersand(Word Index) BEGIN DoAddNormal("&",BackSepString); END static void TeXAddAt(Word Index) BEGIN DoAddNormal("@",BackSepString); END static void TeXAddImm(Word Index) BEGIN DoAddNormal("#",BackSepString); END static void TeXAddPercent(Word Index) BEGIN DoAddNormal("%",BackSepString); END static void TeXAddSSharp(Word Index) BEGIN DoAddNormal(CH_sz,BackSepString); END static void TeXAddIn(Word Index) BEGIN DoAddNormal("in",BackSepString); END static void TeXAddReal(Word Index) BEGIN DoAddNormal("R",BackSepString); END static void TeXAddGreekMu(Word Index) BEGIN DoAddNormal(CH_mu,BackSepString); END static void TeXAddGreekPi(Word Index) BEGIN DoAddNormal("Pi",BackSepString); END static void TeXAddLessEq(Word Index) BEGIN DoAddNormal("<=",BackSepString); END static void TeXAddGreaterEq(Word Index) BEGIN DoAddNormal(">=",BackSepString); END static void TeXAddNotEq(Word Index) BEGIN DoAddNormal("<>",BackSepString); END static void TeXAddMid(Word Index) BEGIN DoAddNormal("|",BackSepString); END static void TeXAddRightArrow(Word Index) BEGIN DoAddNormal("->",BackSepString); END static void TeXAddLongRightArrow(Word Index) BEGIN DoAddNormal("-->",BackSepString); END static void TeXAddLeftArrow(Word Index) BEGIN DoAddNormal("<-",BackSepString); END static void TeXAddLeftRightArrow(Word Index) BEGIN DoAddNormal("<->",BackSepString); END static void TeXDoFrac(Word Index) BEGIN assert_token("{"); *SepString='\0'; BackToken("("); FracState=0; END static void NextFracState(void) BEGIN if (FracState==0) BEGIN assert_token("{"); *SepString='\0'; BackToken(")"); BackToken("/"); BackToken("("); END else if (FracState==1) BEGIN *SepString='\0'; BackToken(")"); END if ((++FracState)==2) FracState=(-1); END static void TeXNewFontType(Word Index) BEGIN CurrFontType=(TFontType) Index; END static void TeXEnvNewFontType(Word Index) BEGIN char NToken[TOKLEN]; SaveFont(); CurrFontType=(TFontType) Index; assert_token("{"); ReadToken(NToken); strcpy(SepString,BackSepString); BackToken(NToken); END static void TeXNewFontSize(Word Index) BEGIN CurrFontSize=(TFontSize) Index; END static void TeXEnvNewFontSize(Word Index) BEGIN char NToken[TOKLEN]; SaveFont(); CurrFontSize=(TFontSize) Index; assert_token("{"); ReadToken(NToken); strcpy(SepString,BackSepString); BackToken(NToken); END static void TeXAddMarginPar(Word Index) BEGIN assert_token("{"); SaveEnv(EnvMarginPar); END static void TeXAddCaption(Word Index) BEGIN char tmp[100]; int cnt; assert_token("{"); if (CurrEnv!=EnvTable) error("caption outside of a table"); FlushLine(); fputc('\n',outfile); SaveEnv(EnvCaption); AddLine(TableName,""); cnt=strlen(TableName); GetTableName(tmp); strcat(tmp,": "); AddLine(tmp," "); cnt+=1+strlen(tmp); LeftMargin=1; ActLeftMargin=cnt+1; RightMargin=70; END static void TeXHorLine(Word Index) BEGIN if (CurrEnv!=EnvTabular) error("\\hline outside of a table"); if (ThisTable.Lines[CurrRow][0]!=Nil) InitTableRow(++CurrRow); ThisTable.LineFlags[CurrRow]=True; InitTableRow(++CurrRow); END static void TeXMultiColumn(Word Index) BEGIN char Token[TOKLEN],*endptr; int cnt; if (CurrEnv!=EnvTabular) error("\\hline outside of a table"); if (CurrCol!=0) error("\\multicolumn must be in first column"); assert_token("{"); ReadToken(Token); assert_token("}"); cnt=strtol(Token,&endptr,10); if (*endptr!='\0') error("invalid numeric format to \\multicolumn"); if (cnt!=ThisTable.TColumnCount) error("\\multicolumn must span entire table"); assert_token("{"); do BEGIN ReadToken(Token); END while (strcmp(Token,"}")!=0); ThisTable.MultiFlags[CurrRow]=True; END static void TeXIndex(Word Index) BEGIN char Token[TOKLEN]; assert_token("{"); do BEGIN ReadToken(Token); END while (strcmp(Token,"}")!=0); END static int GetDim(Double *Factors) BEGIN char Acc[TOKLEN]; static char *UnitNames[]={"cm","mm",""},**run,*endptr; Double Value; assert_token("{"); collect_token(Acc,"}"); for (run=UnitNames; **run!='\0'; run++) if (strcmp(*run,Acc+strlen(Acc)-strlen(*run))==0) break; if (**run=='\0') error("unknown unit for dimension"); Acc[strlen(Acc)-strlen(*run)]='\0'; Value=strtod(Acc,&endptr); if (*endptr!='\0') error("invalid numeric format for dimension"); return (int)(Value*Factors[run-UnitNames]); END static Double HFactors[]={4.666666,0.4666666,0}; static Double VFactors[]={3.111111,0.3111111,0}; static void TeXHSpace(Word Index) BEGIN DoAddNormal(Blanks(GetDim(HFactors)),""); END static void TeXVSpace(Word Index) BEGIN int z,erg; erg=GetDim(VFactors); FlushLine(); for (z=0; z=TABMAX) error("too many tab stops"); n=strlen(OutLineBuffer); for (p=0; pn) break; for (z=TabStopCnt-1; z>=p; z--) TabStops[z+1]=TabStops[z]; TabStops[p]=n; TabStopCnt++; END static void TeXJmpTabStop(Word Index) BEGIN int diff; if (CurrEnv!=EnvTabbing) error("tab trigger outside of tabbing environment"); if (CurrTabStop>=TabStopCnt) error("not enough tab stops"); diff=TabStops[CurrTabStop]-strlen(OutLineBuffer); if (diff>0) DoAddNormal(Blanks(diff),""); CurrTabStop++; END static void TeXDoVerb(Word Index) BEGIN char Token[TOKLEN],*pos,Marker; ReadToken(Token); if (*SepString!='\0') error("invalid control character for \\verb"); Marker=(*Token); strcpy(Token,Token+1); strcpy(SepString,BackSepString); do BEGIN DoAddNormal(SepString,""); pos=strchr(Token,Marker); if (pos!=Nil) BEGIN *pos='\0'; DoAddNormal(Token,""); *SepString='\0'; BackToken(pos+1); break; END else BEGIN DoAddNormal(Token,""); ReadToken(Token); END END while (True); END static void TeXErrEntry(Word Index) BEGIN char Token[TOKLEN]; assert_token("{"); ReadToken(Token); assert_token("}"); assert_token("{"); *SepString='\0'; BackToken("\\"); BackToken("item"); BackToken("["); BackToken(Token); BackToken("]"); ErrState=0; END static void NextErrState(void) BEGIN if (ErrState<3) assert_token("{"); if (ErrState==0) BEGIN *SepString='\0'; BackToken("\\"); BackToken("begin"); BackToken("{"); BackToken("description"); BackToken("}"); END if ((ErrState>=0) AND (ErrState<=2)) BEGIN *SepString='\0'; BackToken("\\"); BackToken("item"); BackToken("["); BackToken(ErrorEntryNames[ErrState]); BackToken(":"); BackToken("]"); BackToken("\\"); BackToken("\\"); END if (ErrState==3) BEGIN *SepString='\0'; BackToken("\\"); BackToken("\\"); BackToken(" "); BackToken("\\"); BackToken("end"); BackToken("{"); BackToken("description"); BackToken("}"); ErrState=(-1); END else ErrState++; END static void TeXWriteLabel(Word Index) BEGIN char Name[TOKLEN],Value[TOKLEN]; assert_token("{"); collect_token(Name,"}"); if (CurrEnv==EnvCaption) GetTableName(Value); else BEGIN GetSectionName(Value); if (Value[strlen(Value)-1]=='.') Value[strlen(Value)-1]='\0'; END AddLabel(Name,Value); END static void TeXWriteRef(Word Index) BEGIN char Name[TOKLEN],Value[TOKLEN]; assert_token("{"); collect_token(Name,"}"); GetLabel(Name,Value); DoAddNormal(Value,BackSepString); END static void TeXWriteCitation(Word Index) BEGIN char Name[TOKLEN],Value[TOKLEN]; assert_token("{"); collect_token(Name,"}"); GetCite(Name,Value); sprintf(Name,"[%s]",Value); DoAddNormal(Name,BackSepString); END static void TeXNewParagraph(Word Index) BEGIN FlushLine(); fputc('\n',outfile); END static void TeXContents(Word Index) BEGIN FILE *file=fopen(TocName,"r"); char Line[200]; if (file==Nil) BEGIN warning("contents file not found."); DoRepass=True; return; END FlushLine(); fprintf(outfile," %s\n\n",ContentsName); while (NOT feof(file)) BEGIN fgets(Line,199,file); fputs(Line,outfile); END fclose(file); END static void TeXParSkip(Word Index) BEGIN char Token[TOKLEN]; ReadToken(Token); do BEGIN ReadToken(Token); if ((strncmp(Token,"plus",4)==0) OR (strncmp(Token,"minus",5)==0)) BEGIN END else BEGIN BackToken(Token); return; END END while (1); END static void TeXNLS(Word Index) BEGIN char Token[TOKLEN],*Repl=""; Boolean Found=True; *Token='\0'; ReadToken(Token); if (*SepString=='\0') switch (*Token) BEGIN case 'a': Repl=CH_ae; break; case 'e': Repl=CH_ee; break; case 'i': Repl=CH_ie; break; case 'o': Repl=CH_oe; break; case 'u': Repl=CH_ue; break; case 'A': Repl=CH_Ae; break; case 'E': Repl=CH_Ee; break; case 'I': Repl=CH_Ie; break; case 'O': Repl=CH_Oe; break; case 'U': Repl=CH_Ue; break; case 's': Repl=CH_sz; break; default : Found=False; END else Found=False; if (Found) BEGIN if (strlen(Repl)>1) memmove(Token+strlen(Repl),Token+1,strlen(Token)); memcpy(Token,Repl,strlen(Repl)); strcpy(SepString,BackSepString); END else DoAddNormal("\"",BackSepString); BackToken(Token); END static void TeXNLSGrave(Word Index) BEGIN char Token[TOKLEN],*Repl=""; Boolean Found=True; *Token='\0'; ReadToken(Token); if (*SepString=='\0') switch (*Token) BEGIN case 'a': Repl=CH_agrave; break; case 'A': Repl=CH_Agrave; break; case 'e': Repl=CH_egrave; break; case 'E': Repl=CH_Egrave; break; case 'i': Repl=CH_igrave; break; case 'I': Repl=CH_Igrave; break; case 'o': Repl=CH_ograve; break; case 'O': Repl=CH_Ograve; break; case 'u': Repl=CH_ugrave; break; case 'U': Repl=CH_Ugrave; break; default : Found=False; END else Found=False; if (Found) BEGIN if (strlen(Repl)>1) memmove(Token+strlen(Repl),Token+1,strlen(Token)); memcpy(Token,Repl,strlen(Repl)); strcpy(SepString,BackSepString); END else DoAddNormal("\"",BackSepString); BackToken(Token); END static void TeXNLSAcute(Word Index) BEGIN char Token[TOKLEN],*Repl=""; Boolean Found=True; *Token='\0'; ReadToken(Token); if (*SepString=='\0') switch (*Token) BEGIN case 'a': Repl=CH_aacute; break; case 'A': Repl=CH_Aacute; break; case 'e': Repl=CH_eacute; break; case 'E': Repl=CH_Eacute; break; case 'i': Repl=CH_iacute; break; case 'I': Repl=CH_Iacute; break; case 'o': Repl=CH_oacute; break; case 'O': Repl=CH_Oacute; break; case 'u': Repl=CH_uacute; break; case 'U': Repl=CH_Uacute; break; default : Found=False; END else Found=False; if (Found) BEGIN if (strlen(Repl)>1) memmove(Token+strlen(Repl),Token+1,strlen(Token)); memcpy(Token,Repl,strlen(Repl)); strcpy(SepString,BackSepString); END else DoAddNormal("\"",BackSepString); BackToken(Token); END static void TeXNLSCirc(Word Index) BEGIN char Token[TOKLEN],*Repl=""; Boolean Found=True; *Token='\0'; ReadToken(Token); if (*SepString=='\0') switch (*Token) BEGIN case 'a': Repl=CH_acirc; break; case 'A': Repl=CH_Acirc; break; case 'e': Repl=CH_ecirc; break; case 'E': Repl=CH_Ecirc; break; case 'i': Repl=CH_icirc; break; case 'I': Repl=CH_Icirc; break; case 'o': Repl=CH_ocirc; break; case 'O': Repl=CH_Ocirc; break; case 'u': Repl=CH_ucirc; break; case 'U': Repl=CH_Ucirc; break; default : Found=False; END else Found=False; if (Found) BEGIN if (strlen(Repl)>1) memmove(Token+strlen(Repl),Token+1,strlen(Token)); memcpy(Token,Repl,strlen(Repl)); strcpy(SepString,BackSepString); END else DoAddNormal("\"",BackSepString); BackToken(Token); END static void TeXNLSTilde(Word Index) BEGIN char Token[TOKLEN],*Repl=""; Boolean Found=True; *Token='\0'; ReadToken(Token); if (*SepString=='\0') switch (*Token) BEGIN case 'n': Repl=CH_ntilde; break; case 'N': Repl=CH_Ntilde; break; default : Found=False; END else Found=False; if (Found) BEGIN if (strlen(Repl)>1) memmove(Token+strlen(Repl),Token+1,strlen(Token)); memcpy(Token,Repl,strlen(Repl)); strcpy(SepString,BackSepString); END else DoAddNormal("\"",BackSepString); BackToken(Token); END static void TeXCedilla(Word Index) BEGIN char Token[TOKLEN]; assert_token("{"); collect_token(Token,"}"); if (strcmp(Token,"c")==0) strcpy(Token,CH_ccedil); if (strcmp(Token,"C")==0) strcpy(Token,CH_Ccedil); DoAddNormal(Token,BackSepString); END static Boolean TeXNLSSpec(char *Line) BEGIN Boolean Found=True; char *Repl=Nil; int cnt=0; if (*SepString=='\0') switch (*Line) BEGIN case 'o': cnt=1; Repl=CH_oslash; break; case 'O': cnt=1; Repl=CH_Oslash; break; case 'a': switch (Line[1]) BEGIN case 'a': cnt=2; Repl=CH_aring; break; case 'e': cnt=2; Repl=CH_aelig; break; default: Found=False; END break; case 'A': switch (Line[1]) BEGIN case 'A': cnt=2; Repl=CH_Aring; break; case 'E': cnt=2; Repl=CH_Aelig; break; default: Found=False; END break; default: Found=False; END if (Found) BEGIN if (strlen(Repl)!=cnt) memmove(Line+strlen(Repl),Line+cnt,strlen(Line)-cnt+1); memcpy(Line,Repl,strlen(Repl)); strcpy(SepString,BackSepString); END else DoAddNormal("\"",BackSepString); BackToken(Line); return Found; END static void TeXHyphenation(Word Index) BEGIN char Token[TOKLEN]; assert_token("{"); collect_token(Token,"}"); AddException(Token); END static void TeXDoPot(void) BEGIN char Token[TOKLEN]; ReadToken(Token); if (*Token=='2') BEGIN if (strlen(CH_e2)>1) memmove(Token+strlen(CH_e2),Token+1,strlen(Token)); memcpy(Token,CH_e2,strlen(CH_e2)); END else DoAddNormal("^",BackSepString); BackToken(Token); END static void TeXDoSpec(void) BEGIN strcpy(BackSepString,SepString); TeXNLS(0); END static void TeXInclude(Word Index) BEGIN char Token[TOKLEN],Msg[TOKLEN]; assert_token("{"); collect_token(Token,"}"); if ((infiles[IncludeNest]=fopen(Token,"r"))==Nil) BEGIN sprintf(Msg,"file %s not found",Token); error(Msg); END else IncludeNest++; END static void TeXDocumentStyle(Word Index) BEGIN char Token[TOKLEN]; ReadToken(Token); if (strcmp(Token,"[")==0) BEGIN do BEGIN ReadToken(Token); if (strcmp(Token,"german")==0) SetLang(True); END while (strcmp(Token,"]")!=0); assert_token("{"); ReadToken(Token); if (strcasecmp(Token, "article") == 0) BEGIN AddInstTable(TeXTable,"section",0,TeXNewSection); AddInstTable(TeXTable,"subsection",1,TeXNewSection); AddInstTable(TeXTable,"subsubsection",3,TeXNewSection); END else BEGIN AddInstTable(TeXTable,"chapter",0,TeXNewSection); AddInstTable(TeXTable,"section",1,TeXNewSection); AddInstTable(TeXTable,"subsection",2,TeXNewSection); AddInstTable(TeXTable,"subsubsection",3,TeXNewSection); END assert_token("}"); END END /*--------------------------------------------------------------------------*/ int main(int argc, char **argv) BEGIN char Line[TOKLEN],Comp[TOKLEN],*p,AuxFile[200]; int z; if (argc<3) BEGIN fprintf(stderr,"calling convention: %s \n",*argv); exit(1); END TeXTable=CreateInstTable(301); IncludeNest=0; if ((*infiles=fopen(argv[1],"r"))==Nil) BEGIN perror(argv[1]); exit(3); END else IncludeNest++; infilename=argv[1]; if (strcmp(argv[2],"-")==0) outfile=stdout; else if ((outfile=fopen(argv[2],"w"))==Nil) BEGIN perror(argv[2]); exit(3); END AddInstTable(TeXTable,"\\",0,TeXFlushLine); AddInstTable(TeXTable,"par",0,TeXNewParagraph); AddInstTable(TeXTable,"-",0,TeXDummy); AddInstTable(TeXTable,"hyphenation",0,TeXHyphenation); AddInstTable(TeXTable,"kill",0,TeXKillLine); AddInstTable(TeXTable,"/",0,TeXDummy); AddInstTable(TeXTable,"pagestyle",0,TeXDummyInCurl); AddInstTable(TeXTable,"thispagestyle",0,TeXDummyInCurl); AddInstTable(TeXTable,"sloppy",0,TeXDummy); AddInstTable(TeXTable,"clearpage",0,TeXDummy); AddInstTable(TeXTable,"cleardoublepage",0,TeXDummy); AddInstTable(TeXTable,"topsep",0,TeXDummyNoBrack); AddInstTable(TeXTable,"parskip",0,TeXParSkip); AddInstTable(TeXTable,"parindent",0,TeXDummyNoBrack); AddInstTable(TeXTable,"textwidth",0,TeXDummyNoBrack); AddInstTable(TeXTable,"evensidemargin",0,TeXDummyNoBrack); AddInstTable(TeXTable,"oddsidemargin",0,TeXDummyNoBrack); AddInstTable(TeXTable,"newcommand",0,TeXNewCommand); AddInstTable(TeXTable,"def",0,TeXDef); AddInstTable(TeXTable,"font",0,TeXFont); AddInstTable(TeXTable,"documentstyle",0,TeXDocumentStyle); AddInstTable(TeXTable,"appendix",0,TeXAppendix); AddInstTable(TeXTable,"makeindex",0,TeXDummy); AddInstTable(TeXTable,"begin",0,TeXBeginEnv); AddInstTable(TeXTable,"end",0,TeXEndEnv); AddInstTable(TeXTable,"item",0,TeXItem); AddInstTable(TeXTable,"bibitem",0,TeXBibItem); AddInstTable(TeXTable,"errentry",0,TeXErrEntry); AddInstTable(TeXTable,"$",0,TeXAddDollar); AddInstTable(TeXTable,"_",0,TeXAddUnderbar); AddInstTable(TeXTable,"&",0,TeXAddAmpersand); AddInstTable(TeXTable,"@",0,TeXAddAt); AddInstTable(TeXTable,"#",0,TeXAddImm); AddInstTable(TeXTable,"%",0,TeXAddPercent); AddInstTable(TeXTable,"ss",0,TeXAddSSharp); AddInstTable(TeXTable,"in",0,TeXAddIn); AddInstTable(TeXTable,"rz",0,TeXAddReal); AddInstTable(TeXTable,"mu",0,TeXAddGreekMu); AddInstTable(TeXTable,"pi",0,TeXAddGreekPi); AddInstTable(TeXTable,"leq",0,TeXAddLessEq); AddInstTable(TeXTable,"geq",0,TeXAddGreaterEq); AddInstTable(TeXTable,"neq",0,TeXAddNotEq); AddInstTable(TeXTable,"mid",0,TeXAddMid); AddInstTable(TeXTable,"frac",0,TeXDoFrac); AddInstTable(TeXTable,"rm",FontStandard,TeXNewFontType); AddInstTable(TeXTable,"em",FontEmphasized,TeXNewFontType); AddInstTable(TeXTable,"bf",FontBold,TeXNewFontType); AddInstTable(TeXTable,"tt",FontTeletype,TeXNewFontType); AddInstTable(TeXTable,"it",FontItalic,TeXNewFontType); AddInstTable(TeXTable,"bb",FontBold,TeXEnvNewFontType); AddInstTable(TeXTable,"tty",FontTeletype,TeXEnvNewFontType); AddInstTable(TeXTable,"ii",FontItalic,TeXEnvNewFontType); AddInstTable(TeXTable,"tiny",FontTiny,TeXNewFontSize); AddInstTable(TeXTable,"small",FontSmall,TeXNewFontSize); AddInstTable(TeXTable,"normalsize",FontNormalSize,TeXNewFontSize); AddInstTable(TeXTable,"large",FontLarge,TeXNewFontSize); AddInstTable(TeXTable,"huge",FontHuge,TeXNewFontSize); AddInstTable(TeXTable,"tin",FontTiny,TeXEnvNewFontSize); AddInstTable(TeXTable,"rightarrow",0,TeXAddRightArrow); AddInstTable(TeXTable,"longrightarrow",0,TeXAddLongRightArrow); AddInstTable(TeXTable,"leftarrow",0,TeXAddLeftArrow); AddInstTable(TeXTable,"leftrightarrow",0,TeXAddLeftRightArrow); AddInstTable(TeXTable,"marginpar",0,TeXAddMarginPar); AddInstTable(TeXTable,"caption",0,TeXAddCaption); AddInstTable(TeXTable,"label",0,TeXWriteLabel); AddInstTable(TeXTable,"ref",0,TeXWriteRef); AddInstTable(TeXTable,"cite",0,TeXWriteCitation); AddInstTable(TeXTable,"hline",0,TeXHorLine); AddInstTable(TeXTable,"multicolumn",0,TeXMultiColumn); AddInstTable(TeXTable,"ttindex",0,TeXIndex); AddInstTable(TeXTable,"hspace",0,TeXHSpace); AddInstTable(TeXTable,"vspace",0,TeXVSpace); AddInstTable(TeXTable,"=",0,TeXAddTabStop); AddInstTable(TeXTable,">",0,TeXJmpTabStop); AddInstTable(TeXTable,"verb",0,TeXDoVerb); AddInstTable(TeXTable,"printindex",0,TeXDummy); AddInstTable(TeXTable,"tableofcontents",0,TeXContents); AddInstTable(TeXTable,"rule",0,TeXRule); AddInstTable(TeXTable,"\"",0,TeXNLS); AddInstTable(TeXTable,"`",0,TeXNLSGrave); AddInstTable(TeXTable,"'",0,TeXNLSAcute); AddInstTable(TeXTable,"^",0,TeXNLSCirc); AddInstTable(TeXTable,"~",0,TeXNLSTilde); AddInstTable(TeXTable,"c",0,TeXCedilla); AddInstTable(TeXTable,"newif",0,TeXDummy); AddInstTable(TeXTable,"fi",0,TeXDummy); AddInstTable(TeXTable,"ifelektor",0,TeXDummy); AddInstTable(TeXTable,"elektortrue",0,TeXDummy); AddInstTable(TeXTable,"elektorfalse",0,TeXDummy); AddInstTable(TeXTable,"input",0,TeXInclude); for (z=0; z0) RestoreFont(); else if (ErrState>=0) NextErrState(); else if (FracState>=0) NextFracState(); else switch (CurrEnv) BEGIN case EnvMarginPar: RestoreEnv(); break; case EnvCaption: FlushLine(); RestoreEnv(); break; case EnvHeading: EndSectionHeading(); RestoreEnv(); break; default: RestoreFont(); END else DoAddNormal(Line,SepString); END FlushLine(); DestroyInstTable(TeXTable); for (z=0; z