//La2ht.cc LaTeX to HTML Converter //Author: Rolf Pfister // Freeware //last modification: 20-Aug-96 #define VERSION "Version 1.07" /* History: 13.Dez.95 Erstellung (Version 1.01) 23.Jan.96 \verb verbessert 1.Feb.96 hochtief() eingefuegt (Unterstuetzung von und ) 22.Feb.96 Kleinigkeiten verbessert 20.Mar.96 tabposition eingefuegt fuer Tabellen der Form {llp{14cm}} 14.Mai.96 caption erweitert fuer Variante mit kleinem anklickbarem Bild 17.Mai.96 Griechische Buchstaben (alpha beta ...) 20.Aug.96 Korrektur fuer {\bf 76}, Zahl wurde als Parameter behandelt, deshalb Beruecksichtigung des 1.Parameters in set_schriftstil(). int fignumber eingefuehrt */ #define UNIX #include #include #include #include //#include #define CASE break;case #define DEFAULT break;default #ifdef UNIX #include #endif #define SPEZIALCHAR '`' #define TILDE '~' /*** Globale Variablen ***/ int fignumber=0; /*** Vordeklarationen ***/ char *file_einlesen(char *name,long *nb); char *la2ht(char *s,FILE *fp2,int endzeichen=0); char *latexcommand2ht(char *s,FILE *fp2,int *lastc); int pars(char **s0,char *p1,char *p2,char *p3,char *p4); int klampars(char **s0,char *p1); void tabstart(FILE *fp2,char *form); void tabende(FILE *fp2); void tabseperator(FILE *fp); void tabnewline(FILE *fp); void tablinefeed(FILE *fp); void set_schriftstil(FILE *fp,int stil,char *args=NULL); void set_schriftgroesse(FILE *fp,int groesse); int index(char *s,int x); char *ohnepunkt(char*); void nachbearbeiten(char *s); void nachbearbeit_write(char *file1,FILE *fp); void liesstring(char**,char*,int c0,int endzeichen,int max=120); void ersetze(char *s,char *p1,char *p2); void comment(char **s0,FILE *fp); char *hochtief(char *s,char *subp,FILE *fp2,int *lastc); int getmacro(char *com,char *arg,char *arg2,FILE *fp2); void putmacro(char *arg,char *arg2,char *arg3); char *insertfignum(char *arg,int fignum); /*** Klassendefinitionen ***/ class string { public: char *s; string(int n) {s=new char[n]; *s=0;} string(char *t) {s=new char[2*strlen(t)+1+80]; strcpy(s,t);} ~string() {delete s;} char *get() {char *t=new char[strlen(s)+1]; strcpy(t,s); return t;} int operator==(char* t); char *operator+=(char*); char *alfa(int c); //nur Buchstaben verwenden (c=Ersatzzeichen für ' ') char *beta(int c); //wie
...
wenn PRE verboten ist }; int string::operator==(char* t) {return strcmp(s,t)==0;} char *string::operator+=(char* t) { char *p; for(p=s;*p;p++) ; while(*p++ = *t++) ; return s; } char *string::alfa(int c0) { char *su=new char[strlen(s)+1], *t,*p; int c; for(t=su,p=s;c= *p++;) if(c==' ') *t++ = c0; else if(isalnum(c)) *t++ = c; *t=0; return su; } char *string::beta(int c0) { char *t,*p; int c1=' ',c; for(t=s,p=s;c= *p++;c1=c) {if(c==' ' && (c1==' ' || *p==0)) c=c0; *t++ =c1=c; } *t=0; return s; } class inhaltsverzeichnis { char **pname,**ptitel; int *pn; int nmax,ni; public: inhaltsverzeichnis(int n) {pname=new (char*)[nmax=n]; ni=0; ptitel=new (char*)[nmax=n]; pn=new int[nmax];} ~inhaltsverzeichnis() {delete pname; delete ptitel; delete pn;} char *put(int n,char *nam,char *tit); void write(FILE *fp); }; char *inhaltsverzeichnis::put(int n,char *nam,char *tit) { char *t=new char[strlen(tit)+1]; int i; strcpy(t,tit); if(ni==nmax) {char **p2=new (char*)[nmax+=nmax]; char **p3=new (char*)[nmax]; int *n2=new int[nmax]; for(i=0;i=0;) fprintf(fp," . ");//provi. fprintf(fp,"",pname[i]); la2ht(ptitel[i],fp); fprintf(fp,"
\n"); } } /*** weitere Vordeklarationen ***/ /**************** Routinen zur Parameterauswertung ********************/ #define MAXARG 2 static char argflag[128]; void setargflags(char *s) { int c; while(c= *s++) {if(c>='a' && c<='z') c -= 'a'-'A'; argflag[c&127]=1; } } main(int argc,char *argv[]) { char quellname[80],zielname[80],*file1,*s; FILE *fp2; int i,j,c; long nb; quellname[0]=zielname[0]=0; for(j=0,i=1;iMAXARG) {printf("La2ht.cc %s\n",VERSION); printf("Anwendung: la2ht Quelle.tex [Ziel.html]\n"); exit(0); } if(*quellname==0) {printf("Quellname:"); scanf("%s",quellname);} if(*zielname==0) sprintf(zielname,"%s.html",ohnepunkt(quellname)); file1=file_einlesen(quellname,&nb); if(nb<=0) {strcat(quellname,".tex"); file1=file_einlesen(quellname,&nb); } if(nb<=0) {printf("'%s' nicht gefunden\n",quellname); exit(0);} if(!(fp2=fopen(zielname,"w"))) {printf("kann '%s' nicht oeffnen\n",zielname); exit(0);} fprintf(fp2,"\n %s converted by La2ht %s \n", quellname,VERSION); fprintf(fp2,"\n"); la2ht(file1,fp2); fprintf(fp2,"\n\n"); fclose(fp2); delete file1; file1=file_einlesen(zielname,&nb); if(nb<=0) {printf("'%s' nicht gefunden\n",zielname); exit(0);} nachbearbeiten(file1); if(!(fp2=fopen(zielname,"w"))) {printf("kann '%s' nicht oeffnen\n",zielname); delete file1; exit(0);} nachbearbeit_write(file1,fp2); fclose(fp2); delete file1; return 0; }/* ende von main */ /*** globale Variablen ***/ static int mathmodus=0, //wird bisher noch nicht ausgewertet intabelle=0, //gesetzt wenn wir innerhalb einer Tabelle sind #define TABSTART0 1 #define TABSTART1 2 #define TABSTART2 3 #define TABSTARTED 4 #define TABBLOCK 5 tabellentyp=0, #define TABLLP 6 tabposition=0, //aktuelle Position in Tabelle schriftstil=0, #define NORMAL 0 #define BOLD 1 #define ITALIC 2 #define EMSCHRIFT 4 schriftgroesse=12, //noch nicht in HTML-Code umgesetzt preverboten=0, //gesetzt wenn
 verboten ist
    pre_zaehler=0; //gesetzt wenn 
 gestartet
static inhaltsverzeichnis inhalt(40);
const int M80=100, //Maximale Grösse eines Namens oder Parameters
          M100=160;

class geklammert
{
 int st,gr;
public:
 geklammert(int stil,int groesse) {st=stil; gr=groesse;}
 void auf() {st=schriftstil; gr=schriftgroesse;}
 void zu(FILE *fp);
};
void geklammert::zu(FILE *fp)
{
 if(st!=schriftstil) set_schriftstil(fp,st);
 if(gr!=schriftgroesse) set_schriftgroesse(fp,gr);
}

static geklammert schweif(0,12);
/*** ende globale Variablen ***/

inline int istzahl(int c) {return isdigit(c) || c=='-';}

void set_schriftstil(FILE *fp,int stil,char *args)
{
 if(schriftstil&BOLD) fprintf(fp,"");
 if(schriftstil&ITALIC) fprintf(fp,"");
 if(schriftstil&EMSCHRIFT) fprintf(fp,"");
 if(stil==BOLD) fprintf(fp,"");
 if(stil==ITALIC) fprintf(fp,"");
 if(stil==EMSCHRIFT) fprintf(fp,"");
 schriftstil=stil;
 if(args) fprintf(fp,"%s",args);
}
void set_schriftgroesse(FILE *fp,int groesse)
{
//provisorisch:
 if(schriftgroesse==100)
   fprintf(fp,"");
 if(groesse==100)
   fprintf(fp,"

"); schriftgroesse=groesse; } char *txt2ht(char *f1,FILE *fp2,int endzeichen=0) { char *s; int c; for(s=f1;(c= *s++) && c!=endzeichen;) {if(c=='%') fprintf(fp2,"%"); else if(c=='<') fprintf(fp2,"<"); else if(c=='>') fprintf(fp2,">"); else if(c=='&') fprintf(fp2,"&"); else if(c=='"') fprintf(fp2,"""); else if((c=='\'' || c=='`') && *s==c) {putc('"',fp2); ++s;} else if(c==SPEZIALCHAR) putc(*s++,fp2); else if(c=='\\' && *s=='"' && s[1]) {fprintf(fp2,"&%cuml;",*++s); ++s;} else putc(c,fp2); } return s; } char *la2ht(char *s,FILE *fp2,int endzeichen) { int c,c1,lastc='\n'; while((c= *s++) && c!=endzeichen) {c1=0; if(c=='%') {comment(&s,fp2); c1=lastc='\n';} //Kommentare uebergehen else if(c=='$') mathmodus^=1; //Mathe-Umschaltzeichen nicht kopieren else if(c=='<') fprintf(fp2,"<"); //HTML-Steuerzeichen else if(c=='>') fprintf(fp2,">"); else if(c=='&') {if(intabelle) tabseperator(fp2); else fprintf(fp2,"&");} else if(c=='"') fprintf(fp2,"""); else if((c=='\'' || c=='`') && *s==c) {putc('"',fp2); ++s;} else if(c=='{') schweif.auf(); else if(c=='}') schweif.zu(fp2); else if(c=='_') {s=hochtief(s,"SUB",fp2,&lastc); c1=1;} else if(c=='^') {s=hochtief(s,"SUP",fp2,&lastc); c1=1;} else if(c=='~') fprintf(fp2," "); else if(c=='\n') {if(intabelle) tablinefeed(fp2); else if(*s=='\n') //zwei Zeilentrenner nacheinander {fprintf(fp2,"\n

\n"); s++;} //ergeben neuen Abschnitt else putc(c,fp2); } else if(c=='\\') {s=latexcommand2ht(s,fp2,&lastc); c1=1;} else putc(c,fp2); //normale Zeichen unveraendert kopieren if(c1==0) lastc=c; } return --s; } char *hochtief(char *s,char *subp,FILE *fp2,int *lastc) { int c; fprintf(fp2,"<%s>",subp); if((c= *s++)=='{') //while((c= *s++) && c!='}' && c!=EOF && c!='\n') putc(c,fp2); {s=la2ht(s,fp2,'}'); c= *s++;} else putc(c,fp2); fprintf(fp2,"",subp); *lastc=c; return s; } int isteinheit(char *s) {return (s[1]=='m' && (*s=='c' || *s=='m'));} int isdummy(char *com) //Kommandos die keine Wirkung haben { static char *list[]={"footnotesize","normalsize","noindent","label", "mbox","epsfxsize","epsfbox","documentclass","usepackage","evensidemargin", "oddsidemargin","topmargin","textwidth","textheight","newcounter", NULL}; char **q,*p; for(q=list;p= *q++;) if(strcmp(com,p)==0) return 1; return 0; } int is_greek(char *s) //LaTeX-Commando == Griechischer Buchstabe ? { static char *list[]={"alpha","gamma","delta","epsilon","varepsilon", "zeta","eta","theta","vartheta","iota","kappa","lambda","mu","nu","xi", "pi","varpi","rho","varrho","sigma","varsigma","tau","upsilon","phi", "varphi","chi","psi","omega", "Gamma","Delta","Theta","Lambda","Xi","Pi","Sigma","Upsilon","Phi","Psi", "Omega",NULL}; char **pp,*p; for(pp=list;(p= *pp)!=NULL;pp++) if(strcmp(p,s)==0) return 1; return 0; } char *latexcommand2ht(char *s,FILE *fp2,int *lastc) { int c,c1; if(!isalpha(*s)) switch(c1= *s++) {case '"': fprintf(fp2,"&%cuml;",*s++); //Umlaute CASE '\\':if(intabelle) {tabnewline(fp2); tabposition=0;} else fprintf(fp2,"
\n"); if(*s=='*') s++; //es kann '\\*' wie '\\' behandelt werden CASE '-': break; default: putc(c1,fp2); } else {string kom(M80),arg(M80),arg2(M80),arg3(M80); c=pars(&s,kom.s,arg.s,arg2.s,arg3.s); if(kom=="verb") {if(!preverboten && *lastc=='\n') {fprintf(fp2,"

");txt2ht(arg.s,fp2);
	 if(*s=='\\' && s[1]=='\\')
	   {s+=2;
	    if(*s=='*') s++; //es kann '\\*' wie '\\' behandelt werden
	   }
	 else //Rest der Zeile auch ins PRE nehmen
	      //dies ist noetig weil 
automatisch neue Zeile macht {string zeilrest(M80); char *t; for(t=zeilrest.s,c=M80; --c>0 && *s && *s!='\n' && (*s!='\\' || s[1]!='\\'); ) {*t++ = *s++;} *t=0; txt2ht(zeilrest.s,fp2); if(*s=='\\' && s[1]=='\\') s+=2; } if(*s=='\n') s++; fprintf(fp2,"

\n"); } else //preverboten txt2ht(arg.beta('.'),fp2); } else if(kom=="input") {long nb; char *file2=file_einlesen(arg+=".tex",&nb); if(nb<=0) printf("kann '%s' nicht finden\n",arg.s); else {la2ht(file2,fp2); delete file2;} } else if(kom=="section" || kom=="subsection" || kom=="subsubsection" || kom=="chapter") {int n=(strlen(kom.s)-7)/3+2; char *name=arg.alfa('_'); name=inhalt.put(n,name,arg.s); fprintf(fp2,"\n",name,n); la2ht(arg.s,fp2); fprintf(fp2,"\n",n); while(*s=='\n') s++; } else if(kom=="begin") {if(arg=="tabular") tabstart(fp2,arg2.s); else if(arg=="itemize") {fprintf(fp2,"
    "); preverboten++;} else if(arg=="Huge") set_schriftgroesse(fp2,100); else if(arg=="normalsize") set_schriftgroesse(fp2,12); else if(arg=="small") set_schriftgroesse(fp2,10); else if(arg=="large") set_schriftgroesse(fp2,14); else if(arg=="tabbing") {if(++pre_zaehler ==1) fprintf(fp2,"
    ");}
            }
        else if(kom=="end")
    	{if(arg=="tabular") {tabende(fp2); while(*s=='\n') s++;}
    	 else if(arg=="itemize") {fprintf(fp2,"
"); preverboten--;} else if(arg=="small" || arg=="Huge" || arg=="large") set_schriftgroesse(fp2,12); else if(arg=="tabbing") {if(--pre_zaehler ==0) fprintf(fp2,"
\n");} } else if(kom=="newpage") fprintf(fp2,"\n
\n"); else if(kom=="it") set_schriftstil(fp2,ITALIC,arg.s); else if(kom=="bf") set_schriftstil(fp2,BOLD,arg.s); else if(kom=="rm") set_schriftstil(fp2,NORMAL,arg.s); else if(kom=="em") set_schriftstil(fp2,EMSCHRIFT,arg.s); else if(kom=="item") fprintf(fp2,"
  • "); else if(kom=="small") set_schriftgroesse(fp2,10); else if(kom=="large") set_schriftgroesse(fp2,14); else if(kom=="Huge") set_schriftgroesse(fp2,100);//provi. else if(kom=="hspace" || kom=="vspace" || kom=="setcounter") ;//provi. else if(kom=="parindent") {if(isteinheit(s)) s+=2;}//provi. else if(kom=="tableofcontents") {fprintf(fp2,"

    Inhaltsverzeichnis

    \n"); fprintf(fp2,"\n"); } else if(kom=="pagenumbering") ;//keine Seitennummerierung in HTML else if(kom=="hline") ;//Linien in Tabellen sind in HTML automatisch else if(kom=="Ae") fprintf(fp2,"Ä"); //in altem LaTeX gebraucht else if(kom=="longrightarrow") fprintf(fp2,"--->"); else if(kom=="leftrightarrow") fprintf(fp2,"<-->"); else if(kom=="epsffile") fprintf(fp2,"\n",arg+=".gif"); else if(kom=="multicolumn") fprintf(fp2,""); else if(kom=="caption") {char *figs=insertfignum(arg.s,fignumber); fprintf(fp2,"\n",figs); fprintf(fp2,"\"GIF-Picture\"%s\n
    \n", figs,figs); } else if(kom=="newcommand" || kom=="renewcommand") putmacro(arg.s,arg2.s,arg3.s); else if(kom=="beta") fprintf(fp2,"ß"); else if(kom=="mu") fprintf(fp2,"µ"); else if(is_greek(kom.s)) fprintf(fp2, "\"\\%s\"\n", kom.s,kom.s); else if(kom=="approx") fprintf(fp2,"~%s",arg.s); else if(kom=="tilde") {if(*arg.s) fprintf(fp2,"&%ctilde;",*(arg.s)); else fprintf(fp2,"~",arg.s); } else if(kom=="backslash") fprintf(fp2,"\\"); else if(kom=="lq") fprintf(fp2,"'"); else if(kom=="rq") fprintf(fp2,"'"); else if(kom=="lbrack") fprintf(fp2,"["); else if(kom=="rbrack") fprintf(fp2,"]"); else if(kom=="lbrace") fprintf(fp2,"{"); else if(kom=="rbrace") fprintf(fp2,"}"); else if(kom=="LaTeX") fprintf(fp2,"LaTeX"); else if(kom=="cdot") fprintf(fp2,"·");//provi. //hier neue Kommandos einfuegen (vor dieser Zeile) else if(getmacro(kom.s,arg.s,arg2.s,fp2)) ; else if(!isdummy(kom.s)) {if(*arg2.s) {printf("\\%s{%s}{%s} unbekannt\n",kom.s,arg.s,arg2.s); fprintf(fp2,"\\%s{%s}{%s}",kom.s,arg.s,arg2.s); } else if(*arg.s) {printf("\\%s{%s} unbekannt\n",kom.s,arg.s); fprintf(fp2,"\\%s{%s}",kom.s,arg.s); } else {printf("\\%s unbekannt\n",kom.s); fprintf(fp2,"\\%s ",kom.s); } } } *lastc = *--s; ++s; return s; } int closeklam(int c) { char kla[]="{}[]()<>",*s; int c1; for(s=kla;c1= *s++;s++) if(c1==c) return *s; return c; } int pars(char **s0,char *p1,char *p2,char *p3,char *p4) { //************************************************************* //Einlesen einer LaTeX-Funktion samt Parameter //Allgemeine Form: \funktion{para1}{para2} // oder: \funktion[para1]{para2} // oder: \funktion Zahl Einheit // oder: \funktion{para1}Zahl // oder: \verb$para1$ ;für $ kann auch anderes Zeichen stehen // oder: \funktion{para1}[para2]{para3} ;z.B. \newcommand //************************************************************* char * s= *s0, * p10=p1; int c,i=M80,verbflag; while((c= *s++) && isalpha(c) && --i>0) *p1++ = c; *p1=0; if(i<=0) printf("ERR-La2ht: zu langer Bezeichner:\n'%s'\n",p10); if(c=='*') c= *s++; verbflag=(strcmp(p10,"verb")==0); *p2= *p3=0; if(c==' ' && istzahl(*s)) c= *s; else --s; if(!isspace(c) && (verbflag || c=='{' || c=='[' || istzahl(c))) {c=klampars(&s,p2); if(strcmp(p10,"caption")!=0) {if(!verbflag && ((c= *s)=='{' || c=='[' || istzahl(c))) c=klampars(&s,p3); if(!verbflag && ((c= *s)=='{' || c=='[' || istzahl(c))) c=klampars(&s,p4); } } *s0=s; return c; } int klampars(char **s0,char *p10) { char * s= *s0, * p1=p10; int c,c1,c2,n,i=M80; if(istzahl(*s)) {*p1++ = c2 = *s++; for(i=M80-1;((c= *s++)=='.' || isdigit(c)) && --i>0;) *p1++ = c; if(c==' ' && isteinheit(s)) {for(i=0;i<3;i++) *p1++ = *s++;} else if(!isspace(c)) --s; } else {c1= *s++; c2=closeklam(c1); for(n=1;(c= *s++) && --i>0;) {if(c==c2) {if(--n==0) break;} else if(c==c1) ++n; *p1++ = c; } } *p1=0; if(i<=0) printf("ERR-La2ht: zu langer Parameter:\n'%s'\n",p10); *s0=s; return c2; } /************************ Tabellen ***************************/ void tabstart(FILE *fp2,char *form) { if(strncmp(form,"llp",3)==0) tabellentyp=TABLLP; else tabellentyp=0; tabposition=0; if(strncmp(form,"lp",2)==0) {fprintf(fp2,"
    \n"); intabelle=TABBLOCK;} else if(index(form,'|')>=0) {fprintf(fp2,"\n"); intabelle=TABSTART1; } else {fprintf(fp2,"\n
    "); intabelle=TABSTART0; } } void tabende(FILE *fp2) { if(!intabelle) printf("fehlendes \\begin{tabular}\n"); else if(intabelle==TABBLOCK) fprintf(fp2,""); else fprintf(fp2,"\n
    \n\n"); intabelle=0; } void tabseperator(FILE *fp) { switch(intabelle) {case TABSTART1: case TABSTART2: fprintf(fp,""); CASE TABSTART0: case TABSTARTED: fprintf(fp,""); tabposition++; CASE TABBLOCK: default:break; } } void tabnewline(FILE *fp) { int n=intabelle,i; if(n==TABBLOCK) fprintf(fp,"\n"); else if(n==TABSTART0) {fprintf(fp,"\n "); intabelle=TABSTARTED; if(tabellentyp==TABLLP) for(i=0;i"); } else if(n==TABSTART1) {fprintf(fp,"\n "); intabelle=TABSTART2;} else {fprintf(fp,"\n "); intabelle=TABSTARTED; if(tabellentyp==TABLLP) for(i=0;i"); } } void tabnewline2(FILE *fp) {if(tabellentyp!=TABLLP) tabnewline(fp);} void tablinefeed(FILE *fp) {if(intabelle!=TABSTARTED || tabellentyp==TABLLP) tabnewline(fp);} /************* file einlesen allgemeine Variante ***************/ filelaenge(char *name,int flag) { char str[80]; FILE *fp; int n; if(flag==0) { #ifdef VAXORALPHA sprintf(str,"DIR/SIZ/output=temp.dat %s;",name); system(str); fp=fopen("temp.dat","r"); if(fp==NULL) return -3; if(fscanf(fp,"%*s %*s %*s %d",&n)!=1) n= -2; fclose(fp); system("DEL temp.dat;"); #endif #ifdef UNIX struct stat st; st.st_mode=st.st_size=0; stat(name,&st); // printf("stat('%s',&st) --> st_mode=%0X _size=%d _blocks=%d\n", // name,st.st_mode,st.st_size,st.st_blocks);//test if((st.st_mode&S_IFMT)==S_IFREG) n=st.st_size; else n= -2; if(n>=0) {if(fp=fopen(name,"r")) fclose(fp); else n= -1;} #endif } else {fp=fopen(name,"r"); if(fp==NULL) return -1; for(n=0;getc(fp)!=EOF;n++) ; fclose(fp); } return n; } char *gross(char *s) { char *gr=new char[strlen(s)+1], *t; int c; for(t=gr;c= *s++;) *t++ = toupper(c); *t=0; return gr; } char *file_einlesen(char *name,long *nb) { char *str,*s; int c; *nb=filelaenge(name,0); if(*nb<=0) {name=gross(name); *nb=filelaenge(name,0); } if(*nb<=0) return NULL; s=str=new char[*nb+1]; FILE *fp=fopen(name,"r"); while((c=getc(fp))!=EOF) *s++ = c; *s=0; return str; } /****************** Spezielle Kommentare auswerten *****************/ void comment(char **s0,FILE *fp) { int c,c0,c1; char * s= *s0; if(strncmp(s,"La2ht ",6)==0) {while(*s++ != ' ') ; switch(c0= *s++) {case '\'': case '"': //z.B. %La2ht '\n' while((c= *s++) && c!=c0) {if(c=='\\') switch(c1= *s++) {case 'n': putc('\n',fp); DEFAULT: putc(c1,fp);} else putc(c,fp); } CASE 'e': case 'v': if(strncmp(s,"rsatz ",6)==0) //z.B. %La2ht ersatz "init" "" {char p1[M100],p2[M100],z2[2*M100]; liesstring(&s,p1,0,'"',M100); liesstring(&s,p2,c0,'"',M100); liesstring(&s,z2,0,'\n',M100); --s; ersetze(z2,p1,p2); la2ht(z2,fp); } CASE 's': if(strncmp(s,"et ",3)==0) //z.B. %La2ht set fignumber=6 {s++; while(*++s==' ') ; if(strncmp(s,"fig",3)==0) {while((c= *++s) && !isdigit(c)) ; sscanf(s,"%d",&fignumber); } else printf("Warning: '%%La2ht set %s' unknown - ignored\n",s); } }//ende switch } while((c= *s++) && c!='\n') ;//Rest der Zeile ueberlesen *s0=s; } void liesstring(char **s0,char *z,int c0,int endzeichen,int max) { char * s= *s0; int c; while((c= *s++) && c!=endzeichen) ; while((c= *s++) && c!=endzeichen && --max>0) {if(c0 && (c=='<' || c=='>')) {*z++ = (c0=='v')?SPEZIALCHAR:'\\'; --max;} *z++ = c; } *z=0; *s0=s; } char *istgleich(char *s,char *t) { while(*s++ == *t++) ; if(*--t==0) return --s; return NULL; } void ersetze(char *s,char *p1,char *p2) //in s erstes p1 durch p2 ersetzen { char *t; for(;*s;s++) if(t=istgleich(s,p1)) {string s2=p2; s2+=t; for(t=s2.s; *s++ = *t++;) ; break; } } /*************** Macros ******************/ class macro { public: macro *next; char *name,*text,*para; macro() {next=NULL; name=text=para=NULL;} ~macro() {if(name) {delete name; delete text;} if(next) delete next;} void put(char *s,char *t); }; static macro macrolist; void putmacro(char *arg,char *arg2,char *arg3) { macro *p,*p2; if(*arg=='\\') arg++; for(p= ¯olist;(p2=p->next)!=NULL;p=p2) if(strcmp(p2->name,arg)==0) {p->next=p2->next; p2->next=NULL; delete p2; p2=p;} p2=new macro[1]; p2->name=new char[strlen(arg)+1]; strcpy(p2->name,arg); if(*arg3==0) {p2->text=new char[strlen(arg2)+1]; strcpy(p2->text,arg2);} else {p2->para=new char[strlen(arg2)+1]; strcpy(p2->para,arg2); p2->text=new char[strlen(arg3)+1]; strcpy(p2->text,arg3); } p->next=p2; } char *substi(char *a1,char *a2,char *str); //provi. int getmacro(char *com,char *arg,char *arg2,FILE *fp2) { macro *p,*p2; for(p= ¯olist;(p2=p->next)!=NULL;p=p2) if(strcmp(p2->name,com)==0) {if(p2->para==NULL) la2ht(p2->text,fp2); else {char *s=substi(arg,arg2,p2->text);//provi. la2ht(s,fp2); delete s; } return 1;//erfolgreich } return 0;//nicht gefunden } char *substi(char *a1,char *a2,char *str) //provi. { char *s0,*s,*t; int c; s0=s=new char[strlen(a1)+strlen(a2)+strlen(str)+80]; for(;c= *str++;) {if(c=='#') {if((c= *str++)=='1') {for(t=a1;c= *t++;) *s++ = c;} else if(c=='2') {for(t=a2;c= *t++;) *s++ = c;} else printf("Warning: Macro too complex\n"); } else *s++ = c; } *s=0; return s0; } /************* Kleinkram ***************/ int index(char *s,int x) //gibt Position von x in s beginnend mit 0 { //wenn nicht vorhanden: -1 int c,i; for(i=0;(c= *s++) && c!=x;i++) ; if(c!=x) i= -1; return i; } char *ohnepunkt(char *name) /* in Filename die Erweiterung .xxx loeschen */ { char c,*s=name; while((c= *s)!='.' && c!=0) s++; if(c=='.') *s='\0'; return name; } char *insertfignum(char *arg,int fignum) { if(fignum<=0) return arg; int c,flag; char *s, *str=new char[strlen(arg)+8]; //max. 6 Stellen + '.' + 0 zufuegen for(flag=1,s=str;c= *arg++;) {if(flag && isdigit(c)) {flag=0; sprintf(s,"%d.",fignum); while(*++s) ;} *s++ = c; } *s=0; return str; } /*************** Nachbearbeitung ******************/ static char *ersatztabelle[]= {"
    ","", "
    ","", "
    ","",
      "
    \n
    ","\n",
    //  "
    \n\n
    ","\n",
      "
    \n\n","
    \n", NULL,NULL }; char *vergleich(char *p,char *s) { int c; while(c= *p++) if(c!= *s++) return NULL; return s; } char *kopieren(char *p,char *z) { int c; while(c= *p++) *z++ = c; return z; } void nachbearbeiten(char *s) { char **tab,*p,*z,*t; int c; for(z=s; c= *s++;) {for(tab=ersatztabelle;;tab++) if((p= *tab++)==NULL) {*z++ = c; break;} else if(*p==c && (t=vergleich(&p[1],s))) {z=kopieren(*tab,z); s=t; break;} } *z=0; } void nachbearbeit_write(char *file1,FILE *fp) { char *s; int c; for(s=file1;c= *s++;) if(c=='<') {if(strncmp(s,"Platzhalter",11)==0) {inhalt.write(fp); while(*s && *s++ != '>') ;} else if(strncmp(s,"BODY>",5)==0) {putc(c,fp); do {c= *s++; putc(c,fp);} while(c!='>'); while(*s=='\n' || strncmp(s,"

    ",3)==0) if(*s++ =='<') s+=2; //Zeilentrenner und

    nach ueberlesen } else putc(c,fp); } else putc(c,fp); }