#define MAX(a,b) ( a>b ? a : b )
char *tampon;
int length=512;
char * nomsort;
int motfini=0;
#include <stdio.h>
#include <stdlib.h>
/* Declarations*/
int yyerror(char * );
#include "rtf.formule.c"
#include "rtf.fields.c"
#include "rtf.motcom.h"
/**************************************************************************************************
** Function name : valdefFD
** --------
** Description : Attribue les valeurs par defaut aux differents champs de formatage du document
** Input : void
** Output : void
**************************************************************************************************/
void valdefFD(void)
{
PZ_FD.FDDEFTAB=(720/20);
PZ_FD.FDPAPERW=(12240/20);
PZ_FD.FDPAPERH=(15840/20);
PZ_FD.FDPSZ=0;
PZ_FD.FDMARGL=(1800/20);
PZ_FD.FDMARGR=(1800/20);
PZ_FD.FDMARGT=(1440/20);
PZ_FD.FDMARGB=(1440/20);
PZ_FD.FDFACINGP=0;
PZ_FD.FDGUTTER=0;
PZ_FD.FDMARGMIRROR=0;
PZ_FD.FDLANDSCAPE=0;
PZ_FD.FDPGNSTART=1;
PZ_FD.FDWIDOWCTRL=0;
}
/**************************************************************************************************
** Function name : puretext
** --------
** Description : Lorsque l'on trouve une chaine de caracteres pure, il faut enlever les
retours a la ligne. En effet WORD coupe les lignes trop longues en plein milieu des mots !!
De meme, il y a des caracteres ASCII 7 bits que TeX considere des mots de commande. Il faut les
transformer dans son propre format. Ceci ne peut etre fait a l'interieur de la grammaire, car
le texte 7 bits est un token a part entiere.
** Input : char * impuretamp: tampon avant d'avoir ete TeXifie.
** Output : char * impuretamp: le meme.
***************************************************************************************************/
char* puretext(char * impuretamp)
{
int i,j,k;
int longtemp=2*length;
char * tamptemp;
tamptemp=(char * ) malloc (longtemp +15);
i=0;
while(i<strlen(impuretamp))
{
if (i==longtemp)
{
longtemp*=2;
tamptemp=(char * ) realloc (longtemp +15);
}
if (impuretamp[i]=='\n')
{
strcpy(&impuretamp[i],&impuretamp[i+1]);
}
else
{
if (impuretamp[i]=='$' || impuretamp[i]=='#' ||
impuretamp[i]=='%' || impuretamp[i]=='&' ||
impuretamp[i]=='_' )
{
if ((strlen(impuretamp)+5)>=length)
{
impuretamp=(char * ) realloc (impuretamp, length + 5);
length+=5;
}
strcpy(&tamptemp[i+1],&impuretamp[i]);
tamptemp[i]='\\';
strcpy(&impuretamp[i],&tamptemp[i]);
i++;
}
else
{
if ((impuretamp[i]=='\\' && impuretamp[i+1]=='{') || (impuretamp[i]=='\\' && impuretamp[i+1]=='}'))
{
/* C'est parfait, on ne fait rien */
}
else
{
if (impuretamp[i]=='\\' && impuretamp[i+1]=='\\')
{
if ((strlen(impuretamp)+15)>=length)
{
impuretamp=(char * ) realloc (impuretamp, length + 5);
length+=15;
}
strcpy(&tamptemp[i],"$\\backslash$");
strcpy(&tamptemp[i+strlen("$\\backslash$")],&impuretamp[i+2]);
strcpy(&impuretamp[i],&tamptemp[i]);
i+=strlen("$\\backslash$");
}
else
{
if (impuretamp[i]=='~')
{
if ((strlen(impuretamp)+5)>=length)
{
impuretamp=(char * ) realloc (impuretamp, length + 5);
length+=5;
}
strcpy(&tamptemp[i],"\\~{}");
strcpy(&tamptemp[i+strlen("\\~{}")],&impuretamp[i+1]);
strcpy(&impuretamp[i],&tamptemp[i]);
i+=strlen("\\~{}");
}
if (impuretamp[i]=='^')
{
if ((strlen(impuretamp)+5)>=length)
{
impuretamp=(char * ) realloc (impuretamp, length + 5);
length+=5;
}
strcpy(&tamptemp[i],"\\^{}");
strcpy(&tamptemp[i+strlen("\\^{}")],&impuretamp[i+1]);
strcpy(&impuretamp[i],&tamptemp[i]);
i+=strlen("\\^{}");
}
if (impuretamp[i]==' ' && FLAG_Equation)
{
if ((strlen(impuretamp)+5)>=length)
{
impuretamp=(char * ) realloc (impuretamp, length + 5);
length+=5;
}
strcpy(&tamptemp[i],"\\, ");
strcpy(&tamptemp[i+strlen("\\, ")],&impuretamp[i+1]);
strcpy(&impuretamp[i],&tamptemp[i]);
i+=strlen("\\, ");
}
if (strlen(impuretamp)>=i+5 && !strncmp(&impuretamp[i],"LaTeX",5))
{
if ((strlen(impuretamp)+5)>=length)
{
impuretamp=(char * ) realloc (impuretamp, length + 5);
length+=5;
}
if(impuretamp[i+5]=='.' || impuretamp[i+5]==',' || impuretamp[i+5]==';'
|| impuretamp[i+5]==':' || impuretamp[i+5]=='!' || impuretamp[i+5]=='?'
|| impuretamp[i+5]==')' || impuretamp[i+5]==']')
strcpy(tamptemp,"\\LaTeX ");
else
strcpy(tamptemp,"\\LaTeX\\ ");
strcat(tamptemp,&impuretamp[i+5]);
strcpy(&impuretamp[i],tamptemp);
i++;
}
}
}
}
};
i++;
}
return impuretamp;
}
/**************************************************************************************************
** Function name : getcode
** -------
** Description : A partir de la chaine de caracteres d'un mot de commande renvoie son type et
leve un flag en cas de non reconnaissance.
** Input : char *Mot_Comm, int * flag
** Output : int: le type de token terminal correspondant.
***************************************************************************************************/
int getcode(char *Mot_Comm, int * flag)
{
int i;
for (i=0;i<NB_Mots_Comm;i++)
if (strncmp(Mot_Comm,TaB_Mot_Comm[i].MC,MAX(strlen(Mot_Comm),strlen(TaB_Mot_Comm[i].MC)))==0)
{
/* ON A TROUVE UN MOT DE COMMANDE */
yylval.motcomm=TaB_Mot_Comm[i].MC;
(*flag)=1;
return TaB_Mot_Comm[i].TK;
};
/* Aucun mot de commande n'a pu etre trouve. */
/*fprintf(stderr,"Unknown Command Word: \t%s\n",Mot_Comm);*/
(*flag)=-1;
return -1;
}
/**************************************************************************************************
** Function name : Avance_Champ
** ------------
** Description : Avance tant que le champ a ignorer n'est pas termine
** Input : void
** Output : void
***************************************************************************************************/
void Avance_Champ(void)
{
char c;
int compteur=1;
do
{
c=fgetc(entree);
if (c=='{') compteur++;
if (c=='}') compteur--;
} while (compteur!=0);
ungetc(c,entree);
}
/**************************************************************************************************
** Function name : Avance_Sauve_Champ
** ------------
** Description : Avance tant que le champ a ignorer n'est pas termine
** Input : void
** Output : void
***************************************************************************************************/
void Avance_Sauve_Champ(void)
{
char c;
int compteur=1;
fclose(auxiliaire);
/* ATTENTION, A partir d'ici, les informations contenues dans le fichier
auxiliaire seront perdues !!!! ( A consommer avec moderation) */
if ((auxiliaire=fopen(nomsort,"w"))==NULL)
{
fprintf(stderr,"FATAL ERROR: Could not open Auxiliary File:%s\n",nomsort);
fclose(entree);
fclose(sortie);
exit(0);
}
do
{
c=fgetc(entree);
if (c=='{') compteur++;
if (c=='}') compteur--;
fprintf(auxiliaire,"%c",c);
} while (compteur!=0);
ungetc(c,entree);
}
/**************************************************************************************************
** Function name : Avance_Sauve_ChampMAC
** ------------
** Description : Avance tant que le champ a ignorer n'est pas termine
** Input : void
** Output : void
***************************************************************************************************/
void Avance_Sauve_ChampMAC(void)
{
char c,c2;
int compteur=0;
int djl=0;
int motEq=0;
fclose(auxiliaire);
/* ATTENTION, A partir d'ici, les informations contenues dans le fichier
auxiliaire seront perdues !!!! ( A consommer avec moderation) */
if ((auxiliaire=fopen(nomsort,"w"))==NULL)
{
fprintf(stderr,"FATAL ERROR: Could not open Auxiliary File:%s\n",nomsort);
fclose(entree);
fclose(sortie);
exit(0);
}
/* On teste le premier (que ce ne soit pas une accolade }) */
c=fgetc(entree);
fprintf(auxiliaire,"\\pzpeq \\\\");
if (c=='}' && (c2=fgetc(entree))=='{')
{
/* On est dans la situation suivante: \|}{\i\f20 o(.... */
/* L'ideal serait de garder les mdc \i et \f20. Mais pour
l'instant on les ignore... */
do
{
c=fgetc(entree);
if (c=='\\')
{
c=fgetc(entree);
if (c=='|')
{
motEq=1;
ungetc('\\',entree);
ungetc(c,entree);
}
}
}
while (c!=' ' && c!='(' && c!=')' && c!=',' && c!=';' && !motEq);
}
else
{
fprintf(auxiliaire,"%c",c);
if (c!='{') c2=fgetc(entree);
fprintf(auxiliaire,"%c",c2);
if (c=='(') { compteur++; djl=1; }
if (c==')') compteur--;
if (c2=='(') { compteur++; djl=1; }
if (c2==')') compteur--;
};
do
{
c=fgetc(entree);
if (c=='(') { compteur++; djl=1; }
if (c==')') compteur--;
fprintf(auxiliaire,"%c",c);
} while (compteur!=0 || !djl);
fflush(auxiliaire);
}
/**************************************************************************************************
** Function name : yylex
** -----
** Description : Analyseur Lexical d'un fichier RTF. Fournit les Tokens a yyparse.
** Input : void
** Output : Token (non specifie: YACC ou BISON le castent)
***************************************************************************************************/
yylex()
{
int i,j,k;
int c;
int flag=0;
int temp;
char cont_inue;
char ctemp;
tampon[0]='\0';
c=fgetc(entree);
if (FLAG_ERROR)
{
if (FLAG_ERROR==1)
{
do
{
i=0;
while (c!='\\' && c!=EOF)
c=fgetc(entree);
if (c==EOF)
return 0;
c=fgetc(entree);
while (c!=' ' && (c>='a' && c<='z'))
{
tampon[i++]=c;
tampon[i]='\0';
c=fgetc(entree);
}
} while (getcode(tampon,&flag)!=PAR);
FLAG_ERROR++;
fprintf(sortie,"\n\n{\\bf W2\\LaTeX : ERROR}\n\n");
return PZERROR;
}
if (FLAG_ERROR==2)
{
FLAG_ERROR=0;
return PAR;
}
}
if (FLAG_Equation!=0 && FLAG_Equation!=-1 &&
(c==' ' || c==0x09 || c=='(' || c==')' || c==','))
{
/* Traitement du texte de l'equation */
yylval.calu=c;
motfini=1;
return c;
}
/* On traite les caracteres de controle. */
if (c == EOF)
{
if (entree==auxiliaire)
{
entree=filetemp;
return yylex();
}
else return 0;
}
if (c == '\n') return (yylex()); /* POUR L'INSTANT ON IGNORERA LES RETOURS A LA LIGNE */
if (c=='{' || c=='}' || c==';')
{
/* yylval.calu=c; */
motfini=1;
return c;
}
/* Traitement des mots de commande */
/* Il faudra verifier la syntaxe pour les caracteres de commande
On supposera que les mots de commande n'excedent pas 128 octets, ce qui est le cas. */
if ( c==0x5c /* Caractere '\' */ )
{
i=0;
c=fgetc(entree);
if (c==0x27) /* Ascii : ' ; Caractere special On ne passe que la valeur hexa. */
{
tampon[i++]=c;
tampon[i]='\0';
temp=getcode(tampon,&flag);
if (flag!=-1) /* Une ceinture et des bretelles ... */
{ tampon[0]=fgetc(entree);
tampon[1]=fgetc(entree);
tampon[2]='\0';
yylval.motcomm=tampon;
return (temp);
}
return(yyerror("Unknown Special Char\n"));
}
if ((FLAG_Equation==0 && (c=='\\')) || (c=='{' || c=='}'))
{
/* Il s'agit d'un caractere reserve et on le traitera comme tel. */
tampon[i++]='\\';
tampon[i++]=c;
tampon[i]='\0';
strcpy(tampon,puretext(tampon));
yylval.pcdata=tampon;
motfini=1;
return PCDATA;
}
if (FLAG_Equation!=0 && c==0x5c)
{
tampon[i++]=c;
tampon[i]='\0';
c=fgetc(entree);
}
if (FLAG_Equation==0)
{
while (c!=' ' && (c>='a' && c<='z'))
{
tampon[i++]=c;
tampon[i]='\0';
c=fgetc(entree);
}
}
else
{
cpt2=0;
while (c!=' ' && ( (c>='a' && c<='z')||(c>='A' && c<='Z') ) )
{
tampon[i++]=c;
tampon[i]='\0';
cpt2++;
c=fgetc(entree);
}
if (cpt2==0) /* On n'a pas identifie le mot de commande correctement */
{
if(c=='|' || c=='{' || c=='}' || c=='(' || c==')' || c=='[' || c==']' )
{
tampon[i++]=c;
tampon[i]='\0';
c=fgetc(entree);
}
}
};
if (c != EOF && c!=' ' && c!='\n') /* On supprime les espaces utilises comme delimiteurs. */
{
motfini=0;
ungetc (c,entree);
}
else
{
motfini=1;
}
tampon[i]='\0';
temp=getcode(tampon,&flag);
if (temp == INFO || temp == OBJECT || temp == DO || temp == XE || temp == TC ) /* ON IGNORE CERTAINS CHAMPS */
{
Avance_Champ();
return temp; /* ON RETOURNE QUAND MEME LE CHAMP CLE POUR LE CONFORT DE LA GRAMMAIRE */
}
if (temp == PIPE )
{
Avance_Sauve_ChampMAC();
moulineFormuleMAC();
entree==auxiliaire; /* LE reste sera lu dans le fichier auxiliaire */
entree=auxiliaire; /* LE reste sera lu dans le fichier auxiliaire */
return temp; /* ON RETOURNE QUAND MEME LE CHAMP CLE POUR LE CONFORT DE LA GRAMMAIRE */
}
if (temp == FLDINST)
{
Avance_Sauve_Champ();
filtrefields();
entree=auxiliaire; /* LE reste sera lu dans le fichier auxiliaire */
return temp; /* ON RETOURNE QUAND MEME LE CHAMP CLE POUR LE CONFORT DE LA GRAMMAIRE */
}
if (flag!=-1)
return (temp);
else
{
if ((strlen(tampon))==0)
{
/* Si ca se toruve c'est un caractere de commande... */
tampon[0]=fgetc(entree);
tampon[1]='\0';
temp=getcode(tampon,&flag);
if (temp == PIPE )
{
Avance_Sauve_ChampMAC();
moulineFormuleMAC();
entree==auxiliaire; /* LE reste sera lu dans le fichier auxiliaire */
entree=auxiliaire; /* LE reste sera lu dans le fichier auxiliaire */
return temp; /* ON RETOURNE QUAND MEME LE CHAMP CLE POUR LE CONFORT DE LA GRAMMAIRE */
}
if (flag!=-1)
return (temp);
/* Non... Il s'agit definitivement d'un code inconnu... */
ungetc(tampon[0],entree);
}
/* Le mot de commande est inconnu */
fprintf(stderr,"\t\t Unknown Command Word: *** %s *** (Skipping)\n",tampon);
c=fgetc(entree); /* On lis le caractere suivant */
if (c==' ')
{
motfini=1;
return (yylex());
}
if (c>='0' && c<='9')
{
ungetc(c,entree);
fscanf(entree,"%d",&yylval.numo);
fprintf(stderr,"\t\tParameter is being Ignored: %d\n",yylval.numo);
c=fgetc(entree);
if (c != ' ') ungetc(c,entree);
motfini=1;
return (yylex());
}
ungetc(c,entree);
return (yylex());
}
}
/* Traitement des valeurs numeriques associees aux mots de commande */
if ( ( (c>='0' && c<='9') || (c=='-') ) && motfini==0 )
{
ungetc (c,entree);
fscanf(entree,"%d",&yylval.numo);
c=fgetc(entree);
if (c != ' ') ungetc(c,entree);
motfini=1;
return NUM;
}
/* Si ce n'est ni un mot de commande, ni un entier, ni un caractere de controle simple, c'est du
texte. */
{
i=0;
cont_inue=1;
while (cont_inue)
{
if (FLAG_Equation==0 && !FLAG_InPict)
{
do
{
/* Si le tampon est plein, il faut l'agrandir */
if (i==length)
{
length*=2;
tampon=(char * ) realloc (tampon, length + 1);
}
if(c==' ' && i==0)
tampon[i++]='\\';
tampon[i++]=c;
tampon[i]='\0';
c=fgetc(entree);
} while (c != EOF && c!='}' && c!='{' && c!=0x5c && c!=';'); /* ATTENTION: IL FAUDRA TRAITER LE ;
DE FACON IDEPENDANTE !!!!!!!!!!!! */
cont_inue=0;
if (c==0x5c) ctemp=fgetc(entree);
if (c==0x5c && (ctemp==0x5c || ctemp=='{' || ctemp=='}') )
{
cont_inue=1;
tampon[i++]=c;
tampon[i]='\0';
c=ctemp;
}
}
else
if (!FLAG_InPict)
do
{
cont_inue=0;
/* Si le tampon est plein, il faut l'agrandir */
if (i==length)
{
length*=2;
tampon=(char * ) realloc (tampon, length + 1);
}
if(c==' ' && i==0)
tampon[i++]='\\';
tampon[i++]=c;
tampon[i]='\0';
c=fgetc(entree);
} while (c != EOF && c!='}' && c!='{' && c!='\\' && c!=',' && c!='('
&& c!=')'); /* ATTENTION: IL FAUDRA TRAITER LE ;
DE FACON IDEPENDANTE !!!!*/
if (FLAG_InPict)
{
while (c != EOF && c!='}' && c!='{' && c!=0x5c && c!=';')
c=fgetc(entree);
if (c!=EOF)
ungetc(c,entree);
cont_inue=0;
}
}
if (FLAG_InPict) { yylval.pcdata="IMAGE"; return PCDATA; }
if (FLAG_Equation==0 && c==0x5c) ungetc(ctemp,entree);
if (c!=EOF)
ungetc(c,entree);
tampon[i]='\0';
if (FLAG_Symbol==0) strcpy(tampon,puretext(tampon));
/*else
{
strcpy(tampon,Rec_Formule(tampon));
}*/
yylval.pcdata=tampon;
motfini=1;
return PCDATA;
}
}
/**************************************************************************************************
** Function name : yyerror
**
** Description :
** Input : char * syyerr
** Output : rapelle yyparse en levant les flags d'Erreur.
**************************************************************************************************/
int yyerror(char * syyerr)
{
if (!FLAG_DebutTeX)
{
fprintf(SORT,"%%\n%% This document was generated using\n%% ");
fprintf(SORT,"w2LaTeX\n%% Bug Reports:
[email protected]\n%%\n\n");
fprintf(SORT,"\\documentstyle[a4]{article}\n");
fprintf(SORT,"%% THIS FILE CONTAINS ERRORS! THE ORIGINAL RTF FILE\n");
fprintf(SORT,"%% HAD A CORRUPTED HEADER\n");
fprintf(SORT,"\n\\parindent = %d pt \n",0/*(PZ_FD.FDDEFTAB)*/);
fprintf(SORT,"\n\\oddsidemargin0cm\n");
fprintf(SORT,"\n\\evensidemargin0cm\n");
fprintf(SORT,"\n\\hoffset%dpt \n",(int)(-72+(PZ_FD.FDMARGL)));
fprintf(SORT,"\n\\textwidth%dpt \n",(int)(614-(PZ_FD.FDMARGL)-(PZ_FD.FDMARGR)));
fprintf(SORT,"\n\\vsize=%dpt\n",(int)(644-(PZ_FD.FDMARGT)));
fprintf(SORT,"\n\\font\\mathex=cmex10\n");
fprintf(SORT,"\n\\font\\pzrm=cmr10\n");
fprintf(SORT,"\n\\pagestyle{myheadings}\n");
fprintf(SORT,"\n\\begin{document}\n");
}
FLAG_DebutTeX=1;
fprintf(stderr, "w2LaTeX: %s: trying to recover....\n",syyerr);
if (FLAG_FIRST_ERROR)
fprintf(stderr, "w2LaTeX: OUTPUT FILE WILL NOT BE CLEAN !\n");
FLAG_ERROR=1;
FLAG_FIRST_ERROR=0;
yyparse();
}
/**************************************************************************************************
** Function name : main
** ----
** Description : Fonction Principale
** Input : void
** Output : void
***************************************************************************************************/
void main(int argc, char * argv[])
{
char pzexit[1024];
char keepnomsort[512];
int pzi=0;
fprintf(stderr,"This is w2LaTeX version 0.1 (Fri Jul 22 1994) by Javier Garmendia,\n");
fprintf(stderr,"Centre International de Rencontres Mathematiques. Luminy. Marseille,\n");
FLAG_DebutTeX=1;
tampon=(char * ) malloc(length+1);
Ligne_Courante_Tabular=(char *) malloc(lengthLCT+1);
valdefFD();
if (argc<=1)
{
fprintf(stderr,"Usage: w2LaTeX filename.rtf\n");
exit(0);
}
if (argc>2)
{
for(pzi=2;pzi<argc;pzi++)
{
if (!strcmp(argv[pzi],"-uglyframes"))
{
pzIntermDef=pzIntermFrame;
pzEndDef=pzEndFrame;
pzStartDef=pzStartFrame;
}
if (!strcmp(argv[pzi],"-debug"))
{
yydebug=1;
}
}
}
if ((entree=fopen(argv[1],"r"))==NULL)
{
fprintf(stderr,"FATAL ERROR: Could not open Specified File::%s\n",argv[1]);
exit(0);
}
nomsort=(char *)malloc(strlen(argv[1])+15);
strcpy(nomsort,argv[1]);
if (!strcmp(&nomsort[strlen(nomsort)-4],".rtf"))
nomsort[strlen(nomsort)-4]='\0';
strcat(nomsort,".tex");
strcpy(keepnomsort,nomsort);
if ((sortie=fopen(nomsort,"w"))==NULL)
{
fprintf(stderr,"FATAL ERROR: Could not open Output File::%s\n",nomsort);
fclose(entree);
exit(0);
}
strcpy(nomsort,argv[1]);
strcat(nomsort,".auxtex");
if ((auxiliaire=fopen(nomsort,"w+"))==NULL)
{
fprintf(stderr,"FATAL ERROR: Could not open Auxiliary File::%s\n",nomsort);
fclose(entree);
fclose(sortie);
exit(0);
}
SORT=sortie;
filetemp=entree;
FLAG_DebutTeX=0;
yyparse();
if (!FLAG_EndTeX)
fprintf(SORT,"\n\\end{document}\n");
fclose(entree);
fclose(sortie);
fclose(auxiliaire);
strcpy(pzexit,"rm -f ");
strcat(pzexit,nomsort);
system(pzexit);
fprintf(stderr,"Output written on %s\nThanks for using w2LaTeX\n",keepnomsort);
}