/*-----------------------------------------------------------------------------
|                                                                             |
|                                  tex8to7                                    |
|                                                                             |
-------------------------------------------------------------------------------
|                                                                             |
| Auteur:           Mael Hill�reau                                            |
| M�l :             [email protected]                                    |
| Web :             http://mael.hillereau.free.fr                             |
| Cr�ation :        01/11/2001                                                |
| Derni�re modif.:  21/08/2003                                                |
| Version:          1.1c                                                      |
| Description:      Conversion de fichiers sources LaTeX : remplacement des   |
|                   caract�res accentu�s fran�ais par leurs �quivalents LaTeX |
|                   dans l'encodage 7bits am�ricain.                          |
|                   Cr�ation d'un nouveau fichier ayant le m�me nom que le    |
|                   fichier de d�part augment� d'un "7".                      |
|                                                                             |
-------------------------------------------------------------------------------
|                                                                             |
| tex8to7 -- Conversion de fichiers sources LaTeX.                            |
| Copyright (C) 2001  Mael Hill�reau                                          |
|                                                                             |
| This program is free software; you can redistribute it and/or               |
| modify it under the terms of the GNU General Public License                 |
| as published by the Free Software Foundation; either version 2              |
| of the License, or (at your option) any later version.                      |
|                                                                             |
| This program is distributed in the hope that it will be useful,             |
| but WITHOUT ANY WARRANTY; without even the implied warranty of              |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               |
| GNU General Public License for more details.                                |
|                                                                             |
| You should have received a copy of the GNU General Public License           |
| along with this program; if not, write to the Free Software                 |
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. |
|                                                                             |
-----------------------------------------------------------------------------*/
#define _VERSION_ "1.1c"
#define _DATE_ "21/08/2003"


/*----------
| inclusions
--*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>


/*----------
| d�finitions
--*/
#define SEP(buf) ((buf == ' ') || (buf == '\t') || (buf == '\n') || (buf == '\r'))
#define TAILLE_MAX_PILE 100


/*----------
| variables globales
--*/
char *pile;
int nbChar;


/*----------
| affichage des messages d'aide
--*/
void aideRapide()
{
       fprintf(stdout,"\nUTILISATION\n\n");
       fprintf(stdout,"    tex8to7 [option] <fichier.tex>\n\n");
       fprintf(stdout,"    tapez \"tex8to7 -?\" pour une aide compl�te.\n\n");
}
void aideComplete()
{
       fprintf(stdout,"\nNOM\n\n");
       fprintf(stdout,"    tex8to7 -- Conversion de fichiers sources LaTeX.\n\n");
       fprintf(stdout,"\nSYNOPSIS\n\n");
       fprintf(stdout,"    tex8to7 [option] <fichier.tex>\n\n");
       fprintf(stdout,"\nDESCRIPTION\n\n");
       fprintf(stdout,"    Remplace les caract�res accentu�s par leurs �quivalents LaTeX dans\n");
       fprintf(stdout,"    l'encodage 7bits am�ricain. Le r�sultat est plac� dans un fichier ayant\n");
       fprintf(stdout,"    pour nom <fichier.tex7>.\n\n");
       fprintf(stdout,"\nOPTIONS\n\n");
       fprintf(stdout,"    -?, -h ou --help\n");
       fprintf(stdout,"        Affiche cette aide.\n\n");
       fprintf(stdout,"    -v ou --version\n");
       fprintf(stdout,"        Affiche la version.\n\n");
}
void version()
{
       fprintf(stdout,"tex8to7 version %s, %s - Conversion de fichiers sources LaTeX.\nCopyright (C) 2003 Mael Hill�reau\n",_VERSION_,_DATE_);
}


/*----------
| �criture d'une chaine de caract�res dans le fichier "fich"
--*/
void ecrire(char *buf, FILE *fich, int len)
{
       if( !fwrite(buf, sizeof(char), len, fich) )
       {
               printf("Erreur d'�criture !");
               exit(2);
       }
}

/*----------
| fermeture du fichier "fich"
--*/
void fermer(FILE *fich, char *nom)
{
       if( fclose(fich) )
       {
               printf("Erreur lors de la fermeture du fichier %s.\n", nom);
               exit(3);
       }
}

/*----------
| �limination d'une fin de ligne
--*/
void avalerligne(FILE *fich_e, FILE *fich_s, char *pbuf)
{
       while(fread(pbuf, sizeof(char), 1, fich_e) && *pbuf != '\n')
               ecrire(pbuf, fich_s, 1);
       ecrire(pbuf, fich_s, 1);
}

/*----------
| empiler un caract�re
--*/
void empiler(char c)
{
       if( nbChar < TAILLE_MAX_PILE )
       {
               pile[nbChar]=c;
               nbChar++;
       }
}

/*----------
| d�piler un caract�re
--*/
char depiler()
{
       if( nbChar > 0 )
       {
               nbChar--;
               return pile[nbChar];
       }
       else
               return '\0';
}

/*----------
| renvoie le caract�re en haut de la pile
--*/
char tete()
{
       if( nbChar > 0 )
               return pile[nbChar-1];
       else
               return '\0';
}

/*----------
| fonction principale
--*/
main(int argc, char **argv)
{
       FILE *fich_e, *fich_s;
       char *nom_fich_s, *ext;
       char buf, antebuf;

       ext = (char*) malloc(sizeof(char)*5);
       strcpy(ext, "7");

       /* v�rification de la syntaxe. */
       if( argc < 2 || argc > 3 )
       {
               aideRapide();
               exit(1);
       }
       if( !strcmp(argv[1],"-v") || !strcmp(argv[1],"--version") )
       {
               version();
               exit(0);
       }
       if( !strcmp(argv[1],"-?") || !strcmp(argv[1],"-h") || !strcmp(argv[1],"--help") )
       {
               aideComplete();
               exit(0);
       }
       if( argc != 2 )
       {
               aideRapide();
               exit(1);
       }

       /* ouverture du fichier source. */
       if( !(fich_e = fopen(argv[1], "r")) )
       {
               printf("Impossible d'ouvrir le fichier source %s.\n", argv[1]);
               exit(1);
       }

       /* cr�ation du nouveau fichier source. */
       nom_fich_s = (char*) malloc((strlen(argv[1])+strlen(ext)+1)*sizeof(char));
       strcpy(nom_fich_s, argv[1]);
       strcat(nom_fich_s, ext);
       if( !(fich_s = fopen(nom_fich_s, "w+")) )
       {
               printf("Impossible d'ouvrir le fichier %s en �criture.\n", nom_fich_s);
               exit(1);
       }

       /* initialisation de la pile */
       pile = (char*) malloc(sizeof(char)*TAILLE_MAX_PILE);
       nbChar = 0;

       /* traduction caract�re par caract�re. */
       antebuf = '\0';
       while(fread(&buf, sizeof(char), 1, fich_e))
       {
               if(buf == '�')                                          /* a */
                       ecrire("\\`{a}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\'{a}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\^{a}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\~{a}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\\"{a}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\ae ", fich_s, 4);
               else if(buf == '�')                                     /* A */
                       ecrire("\\`{A}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\'{A}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\^{A}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\~{A}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\\"{A}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\AE ", fich_s, 4);
               else if(buf == '�')                                     /* c */
                       ecrire("\\c{c}", fich_s, 5);
               else if(buf == '�')                                     /* C */
                       ecrire("\\c{C}", fich_s, 5);
               else if(buf == '�')                                     /* e */
                       ecrire("\\`{e}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\'{e}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\^{e}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\\"{e}", fich_s, 5);
               else if(buf == '�')                                     /* E */
                       ecrire("\\`{E}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\'{E}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\^{E}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\\"{E}", fich_s, 5);
               else if(buf == '�')                                     /* i */
                       ecrire("\\`{\\i}", fich_s, 6);
               else if(buf == '�')
                       ecrire("\\'{\\i}", fich_s, 6);
               else if(buf == '�')
                       ecrire("\\^{\\i}", fich_s, 6);
               else if(buf == '�')
                       ecrire("\\\"{\\i}", fich_s, 6);
               else if(buf == '�')                                     /* I */
                       ecrire("\\`{I}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\'{I}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\^{I}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\\"{I}", fich_s, 5);
               else if(buf == '�')                                     /* n */
                       ecrire("\\~{n}", fich_s, 5);
               else if(buf == '�')                                     /* N */
                       ecrire("\\~{N}", fich_s, 5);
               else if(buf == '�')                                     /* o */
                       ecrire("\\`{o}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\'{o}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\^{o}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\~{o}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\\"{o}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\oe ", fich_s, 4);
               else if(buf == '�')                                     /* O */
                       ecrire("\\`{O}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\'{O}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\^{O}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\~{O}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\\"{O}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\OE ", fich_s, 4);
               else if(buf == '�')                                     /* u */
                       ecrire("\\`{u}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\'{u}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\^{u}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\\"{u}", fich_s, 5);
               else if(buf == '�')                                     /* U */
                       ecrire("\\`{U}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\'{U}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\^{U}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\\"{U}", fich_s, 5);
               else if(buf == '�')                                     /* y */
                       ecrire("\\'{y}", fich_s, 5);
               else if(buf == '�')
                       ecrire("\\\"{y}", fich_s, 5);
               else if(buf == '�')                                     /* Y */
                       ecrire("\\'{Y}", fich_s, 5);
               else if(buf == '"')                                     /* guilemets */
               {
                       if( antebuf != '\\' )
                       {
                               switch(tete())
                               {
                               case '{' :
                               case '\0' :
                                       ecrire("\\og ", fich_s, 4);
                                       empiler('<');
                                       break;
                               case '<' :
                                       ecrire("\\fg ", fich_s, 4);
                                       depiler();
                                       break;
                               }
                       }
                       else /* doubles-c�tes */
                       {
                               ecrire("\"", fich_s, 1);
                       }
               }
               else if(antebuf != '\\' && buf == '{')          /* accolades */
               {
                       empiler('{');
                       ecrire(&buf, fich_s, 1);
               }
               else if(antebuf != '\\' && buf == '}')
               {
                       while( (depiler() != '{') && (depiler() != '\0') );
                       ecrire(&buf, fich_s, 1);
               }
               else if( antebuf != '\\' && buf == '%' )        /* commentaires */
               {
                       ecrire(&buf, fich_s, 1);
                       avalerligne(fich_e, fich_s, &buf);
               }
               else                                                                            /* caract�res classiques */
                       ecrire(&buf, fich_s, 1);
               if( antebuf == '\\' && buf =='\\' )
                       antebuf = '\0';
               else
                       antebuf = buf;
       }

       /* lib�ration des ressources. */
       fermer(fich_e, argv[1]);
       fermer(fich_s, nom_fich_s);
       printf("le ficher %s a �t� cr�� avec succ�s.\n", nom_fich_s);
       free(nom_fich_s);
       free(ext);
       free(pile);

       exit(0);
}