W2LaTEX: Traducteur de Formats Descripteurs de Texte

Javier Garmendia

jgarmend@cyberspace.org

Pour le Centre International de Rencontres Mathématiques

Jean-Louis Maltret

jlm@cirm.univ-mrs.fr

Juin-Juillet 1994

Abstract

W2LaTEX est un outil de conversion entre deux formats descripteurs de texte, permettant de traduire un document rédigé sous certaines versions de Word\begin{matrix}c \\ ◯ \end{matrix}pour obtenir du code LaTEX. Le document source pour W2LaTEX devra être, afin de faciliter la portabilité, en RTF (Rich Text Format), un format propriétaire de Microsoft\begin{matrix}c \\ ◯ \end{matrix}.

W2LaTEX n’utilise pas les fonctions créées par Paul Dubois pour réaliser des lecteurs RTF. Ceci présente en partie l’avantage d’avoir une reconnaissance propre du document d’origine en suivant les spécifications de Microsoft pour Word 6.0. Il est constitué d’un seul programme executable, sans feuilles de style, sans lybraries à installer. On peut attendre de W2LaTEX une conversion de documents contenant des paramètres de présentation et de mise en page, mais aussi de formules mathématiques, et de certains types de tableaux.

Ce document contient des informations techniques sur le programme.

Table des matières

1 Considérations Générales 3 1.1 Les différents types de tokens . . . . . . . . . . . . . . . . . . . . 3 1.2 La structure d’un mot de commande RTF . . . . . . . . . . . . . 4 1.3 Les différents états . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.4 L’analyseur lexical . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.5 Le texte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.6 Les environnements . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.7 Les formules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.8 Les Fontes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.9 L’entête LaTEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.10 Les tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.11 Autres objets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.12 Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.13 Améliorations à réaliser . . . . . . . . . . . . . . . . . . . . . . . 9 1.14 Comment réaliser des extensions . . . . . . . . . . . . . . . . . . 9

2 Fichiers sources et fonctions incluses. 10 2.0.1 rtf.lex.c . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.0.2 rtf.formule.c . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.0.3 rtf.fonts.c . . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.0.4 rtf.context.c . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.0.5 rtf.ascii . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.0.6 rtf.fields.c . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.0.7 rtf.output . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.0.8 rtf.tab.c . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.0.9 rtf.motcom.h . . . . . . . . . . . . . . . . . . . . . . . . 12

3 Documents de Référence 13

4 Disclaimer 14

1 Considérations Générales

1.1 Les différents types de tokens

Le but de l’analyseur lexical est de découper le texte à analyser en tokens qui seront transmis à la fonction réalisant l’analyse gramaticale (que nous appellerons yyparse). Cette fonction vérifie la correction syntaxique du texte original, et détermine à chaque instant quelle construction a été réalisée, et ce que cela représente.

Nous avons declaré plusieurs sortes de tokens, car le type de leur valeur sémantique variera pour certains d’entre eux. Bison (et bien sûr Yacc aussi) imposent la limitation suivante au niveau de l’analyse semantique des tokens:

Seuls les tokens de type char pourront avoir une valeur sémantique permettant de les différentier gramaticalement.

Ainsi, nous pourrons déclarer des règles de grammaire du style:

expression: terme operateur terme;

Où opérateur est un + ou un -; Mais il est aussi possible de faire:

expression: terme ’+’ terme | terme ’-’ terme ;

Cette dernière règle prendra en compte la valeur du token intermédiaire pour déterminer s’il s’agit d’une addition ou d’une soustraction. Par contre, il n’est pas possible de passer un mot de commande composé de plusieurs caractères ou ayant une structure plus complexe. Par exemple:

racine: ’sqrt’ expression;

n’est pas une règle valable.

Il faut donc avoir un analyseur lexical qui fasse la relation entre les chaines de caractères et des entiers, qui seront des tokens typés comme des chaines de charactères. Ceci afin de récupérer la valeur sémantique pour un traitement ultérieur. En reprenant l’exemple précédent, on déclarerait:

%token <char *> SQRT racine: SQRT expression;

et l’analyseur lexical attriburait:

yylval=”sqrt”; return SQRT;

Dans notre cas, nous aurons besoin de plusieurs types de tokens. Un type pour les mots de commande. Un autre pour les valeurs numériques, ainsi qu’un type pour le texte. Nous rajouterons en plus un type pour les caractères individuels, et un type pour les caractères qui sont un mot de commande. Cette declaration Bison se fait de la façon suivante:

%union { char calu; int numo; char* motcomm; char carcomm; char* pcdata; }

dans le fichier de grammaire. Ensuite il faudra typer les tokens.

1.2 La structure d’un mot de commande RTF

Un mot de commande RTF est composé des éléments suivants:

– Le caractère ”\”.

– Des caractères alphabéthiques minuscules.

– Un éventuel paramètre chiffré.

– Un séparateur.

– Dans le cas où un paramètre numérique est présent, il n’est pas nécessaire d’avoir de séparateur.

– Dans les autres cas, le séparateur peut être: ”\”, ”{”, ”}, ”;”, ” ”.

– Si le séparateur est un espace ” ”, il sera ignoré. Sinon, le séparateur sera transmis comme token à la prochaine analyse.

1.3 Les différents états

Lors de l’analyse du code RTF, il faut tenir compte de l’etat contextuel pour effectuer l’analyse lexicale differemment. Il y a plusieurs etats:

1. RTF:

C’est le cas standard. On analyse et reconnait les mots de commande et les passages de texte. On tiens compte aussi des caractères de commande comme dècrit plus bas.

2. Equation:

Si on se trouve dans ce mode, il faut tenir en compte le fait que l’on a modifié le fichier d’entrée, et qu’il s’agit maintenant du fichier auxiliaire. Les caractères de commande prennent une signification particuliaire.

3. Erreur:

On a détecté une erreur, et on analyse de façon à pouvoir la corriger. Il faut alors sauter des morceaux de RTF (et donc perdre des informations) mais de façon à en conserver le maximun.

1.4 L’analyseur lexical

La structure de l’analyseur lexical est la suivante:

1. Si on est en état de traitement des erreurs:

(a) Si c’est le premier token demandé juste après la détection de l’erreur: On avance jusqu’au debut du paragraphe suivant, et on retourne le token PZERROR après avoir inséré dans le fichier de sortie le message d’erreur en LaTEX.

(b) Si c’est le deuxième:

On retourne PAR, et on anule l’état de traitement des erreurs.

2. On lit un caractère dans le fichier d’entrée:

3. Si on est en mode Equation et si c’est un délimiteur d’équation: On le retourne.

4. Si on a trouvé la fin du fichier d’entrée:

(a) Si on était en mode Equation (fichier d’entrée auxiliaire), on replace le bon fichier d’entrée pour la suite.

(b) Sinon, on a terminé l’analyse.

5. S’il s’agit d’un retour à la ligne:

On l’ignore: RTF coupe les lignes comme il veut.

6. S’il s’agit d’un caractère délimiteur: ’{’ ’}’ ’;’ On le retourne.

7. S’il s’agit d’un début de mot de commande: ’\’ (a) On lit le reste de la commande.

(b) En tenant compte des caractères spéciaux: ’{’ ’}’ ’\’ ’;’ et en vérifiant que le mot de commande existe.

(c) Si le mot de commande n’existe pas ou n’est pas connu, il est ignoré.

(d) S’il s’agit d’un caractère de contrôle, on lit le paramètre et on le passe a yyparse.

(e) On élimine les espaces utilisés comme délimiteurs.

(f) Il faut tenir compte aussi des particularités du mode équation.

8. S’il s’agit d’un nombre et que le mot de commande lu précédemment acceptait un paramètre chiffré:

On lit les caractères composant le nombre et on le passe a yyparse.

9. Si ce n’est ni un mot de commande, ni un entier, ni un caractère de contrôle simple, c’est du texte.

(a) On le range dans un tampon, et on passe a yyparse un token PC-DATA avec pour valeur sémantique le pointeur sur le tampon.

(b) Il faut tenir compte aussi des particularités du mode équation.

1.5 Le texte

Les portions de texte pur 7bits sont considérées comme des tokens a part entiere et d’un seul bloc. Le programme W2LaTEX possède des instructions permettant de vérifier que l’on n’excède pas la taille des tampons alloues, auquel cas le tampon est rallongé. Ceci permet de traiter les blocs de texte en suivant les spécifications, et où la seule limitation de place serait due à un manque de mémoire de la machine (ou de mémoire allouée par process). Ce texte sera transcrit tel quel dans le fichier LaTEX de destination.

Une seule limitation est prévue à cet effet: certains caractères 7 bits ont une signification particuliaire pour LaTEX. Ils seront traduits en leur equivalent par la fonction puretext. (e.g.: $ / ...).

1.6 Les environnements

La traduction des differents environnements est faite dès la reconnaissance d’un début d’environnement. C’est à dire, que l’on n’attend pas la fin d’un paragraphe, ou d’une portion de texte dans un environnement particulier pour le transcrire. Ceci facilite le traitement Bison, mais se montre problématique parfois. Pour faciliter la tâche, nous avons implementé de nombreuses variables globales, à titre de FLAGS, qui sont levées au moment de l’établissement d’un envirronnement, et qui sont baissées lors de la fermeture du mode en question.

Par exemple, dès que l’on trouve le mot de commande RTF ’qc’ qui signifie que le paragraphe suivant va être centré, W2LaTEX produit sur le fichier de sortie l’equivalent LaTEX: ’\begin{center}’. Ensuite, lors de la fin du paragraphe, il faut vérifier le contexte. Si RTF ne le précise pas autrement, les paragraphes suivants seront aussi centrés, et donc on n’a rien à faire. Mais si on retrouve la commande RTF ’pard’, il faut remettre tous les flags a 0, et fermer tous les environnements. Heureusement, le systeme de drapeaux fonctionne car en RTF on ne peut pas imbriquer deux environnements conflictifs. Et dans le cas où des environnements de nature différente seraient présents simultanément, ils seront hiérarchisés, et leur ordre de priorité sera inversé lors de la fermeture. A titre d’exemple, le typage des caracteres (bold, italique ...) est moins prioritaire que le typage des paragraphes (centré ...).

1.7 Les formules

Les formules ne font pas partie de RTF lui-même, et les spécifications correspondantes sont fonction de l’aplication qui a généré le document. En conséquence, il faudra re-programmer les fonctions de traitement de ces champs pour des documents générés par d’autres aplications que Word 6.0 et que les versions 5.0 pour Mac et 2.0 pour PC qui sont celles qui ont déjà été implémentées.

Les formules font partie d’un ensemble de champs només a juste titre ’fields’ dans les specifications RTF. Nous disposons des spécifications des fields de Word 6.0, qui ressemblent fortement (aux majuscules, symboles delimiteurs, et quelques mots de commande près) aux versions précédentes de Word pour Mac et PC.

Remarquons qu’il existe toute une panoplie de ’fields’ propres a Word qui n’ont pas été considérés dans la version actuelle de W2LaTEX.

1.8 Les Fontes

Nous n’avons pas tenté d’implémenter de nouvelles polices de caractères pour ne pas rentrer en conflict avec des configurations où elles ne seraient pas présentes. Donc, toutes les polices sont transformées en cmr, aux exceptions suivantes:

1. La police Symbol (Microsoft garanti (?) que cette police aura la même structure sur Mac que sur PC). Elle est entièrement retranscrite avec les équivalents LaTEX lorsque ces équivalences ou approximations existent. Sinon, un symbole @ sera utilisé.

2. Les polices non proportionelles (Courier...) qui seront transcrites en ’tt’.

Cette correspondance entre les polices se trouve dans le fichier rtf.fonts.c dans le tableau EqFontsRTF TeX. Toute personalisation est aisée par edition de ce fichier et recompilation. Les correspondances entre les symboles se font dans le même fichier au sein du tableau FontSymboles.

Dans le cas où W2LaTEX serait portè pour une utilisation sur un systeme avec d’autres polices ou symboles (cf AMS), l’édition de ces tableaux et des constantes définissant les tailles des dits tableaux devrait être aisée.

Il fallait se fixer une police par defaut. Et surtout une taille de police. Le choix a été porté sur la valeur prise par Word par defaut lors de l’installation première du logiciel: 10pt. Une table se trouvant dans ce même fichier (rtf.fonts.c) décrit la correspondance entre les tailles des polices en nombre de points et les paramètres LaTEX (\small, \Huge, ...). Notons que cette table a été établie à partir des données trouvées dans le manuel de LaTEX, correspondant au style 10pt.

1.9 L’entête LaTEX

La taille de la page par defaut est suposée A4. La feuille de style LaTEX correspondante étant un standard, ca nous a semblé le plus judicieux. Toute modification peut se faire dans la grammaire (rtf.y) à la ligne decrivant la regle

input.

Les marges sont fixées en fonction des paramètres fournis par le fichier RTF, ainsi que les tailles des indentations, et quelques redéfinitions de noms de polices standard.

Cette redéfinition des polices est due à la mauvaise découpe en blocs de RTF. En effet, certains parametres RTF sont donnés en plein milieu d’un bloc, et on ne sait pas quand est-ce qu’ils vont avoir fin. Ainsi, il est possible de transcrire des blocs sans délimiteurs de début et de fin de bloc. Pour faire en sorte que LaTEX accepte ces changements, il faut forcer un changement de police complètement. Vous trouverez une nouvelle instruction (la seule) introduite par W2LaTEX qui définit simplement la police cmr10. Il s’agit de la commande ’\pzrm’.

1.10 Les tableaux

Le côté le plus flou de W2LaTEX se situe certainement au niveau des tableaux. S’ils sont traduits, leur structure de tableau n’est pas conservée. Ils ne seront pas encadrés (du moins proprement). Mais le look LaTEX sera conservé.

Ceci est du à la liberté suivante permise en RTF et pas en LaTEX. En RTF on peut avoir une cellule d’un tableau qui soit composée de plusieurs paragraphes, ce qui (sauf erreur de ma part), n’est pas possible directment en LaTEX . A moins de... transformer le contenu des tableaux en minipages. C’est ce que nous avons fait. Chaque cellule d’un tableau est une minipage. Ces minipages sont juxtaposées sur une meme ligne pour former une ligne du tableau. Heureusement, lorsque LaTEX centre toutes ces minipages (par defaut; on peut demander autre chose aussi :-) sur la ligne en cours, ce qui fait que l’aspect du tableau, hormis les cadres, sera le même.

De notables améliorations sont à aporter sur ce point là. Nous avons essayé de mettre ces minipages dans un tableau, mais le resulat n’était pas celui espéré, car les cellules dans RTF sont données par leur largeur, et ca fait en géneral déborder le tableau de la page. Nous avons quand même laissé l’option d’encadrer chacune des minipages à l’aide d’une fbox. Le resultat n’est pas beau. Pour l’obtenir, il suffit d’inclure à la fin de la ligne de commande l’option ’-uglyframes’:

> w2latex inputfile.rtf -uglyframes

1.11 Autres objets

Toutes les règles de grammaire (sauf ommission) correspondant à des objets OLE ou aux images, ont été codées dans le fichier de grammaire: rtf.y. Ils ne sont pas traités pour l’instant. Certains sont irréalisables (inclusion de documents générés par des tableurs...).

Les formats étant extrèmement nombreux, il faudrait toute une panoplie de convertisseurs.

1.12 Images

Les images peuvent être codées de nombreuses façons, et sous différents formats. Les plus courrants sont le Windows Metafile et le format de MacDraw. Ne possedant pas les spécifications de ces formats d’images, nous laisserons un cadre blanc de la taille (approchée) de l’image dans le document LaTEX généré.

La taille des images étant codée parfois en points, parfois en twips, parfois en pixels... il est possible que pour des images générées avec des logiciels de dessin particuliers, il y ait un problème de taille des cadres blancs.

1.13 Améliorations à réaliser

Certains points restent sans doute à améliorer. En particulier le traitement des tableaux, les nouveaux fields, et d’éventuels nouveaux formats de formules pour des documents générés par d’autres applications ou d’autres versions de Word.

Il serait intéressant de pouvoir disposer de traducteurs de formats d’images pour obtenir du post-script inclus dans le fichier LaTEX obtenu. Ceci serait possible, car les images (quel que soit leur format, sont transcrites en hexadécimal dans le fichier RTF. Il est donc possible d’en faire un fichier de sortie binaire.

1.14 Comment réaliser des extensions

En ce qui concerne les formules, il suffit de voir le formatage différent des formules MAC ou PC. Ces deux formats ont été traités en parallèle, et un troisième format s’inserrerait de la même façon.

Pour les tableaux, il faudrait peut-être repartir de la grammaire. Et surtout trouver une astuce pour pouvoir tenir compte des encadrements et autres paramètres de formatage.

Les fields sont entièrement traités dans le fichier rtf.fields.c, qu’il suffirait de completer par de nouvelles fonctions les traitant, ainsi que leur détection au même point que se fait celle des équations.

2 Fichiers sources et fonctions incluses.

2.0.1 rtf.lex.c

Function name : valdefFD Description : Attribue les valeurs par defaut aux differents champs de formatage du document

Function name : puretext Description : Lorsque l’on trouve une chaine de caractères pure, il faut enlever les retours à la ligne. En effet WORD coupe les lignes trop longues en plein milieu des mots !! De même, il y a des caractères ASCII 7 bits que LaTEX considère comme des mots de commande. Il faut les transformer dans son propre format. Ceci ne peut etre fait à l’interieur de la grammaire, car le texte 7 bits est un token à part entière.

Function name : getcode Description : A partir de la chaine de caractères d’un mot de commande renvoie son type et lève un flag en cas de non reconnaissance.

Function name : Avance Champ Description : Avance tant que le champ à ignorer n’est pas terminé

Function name : Avance Sauve Champ

Description : Avance tant que le champ à ignorer n’est pas terminé et le sauve dans un fichier auxiliaire

Function name : Avance Sauve ChampMAC

Description : Avance tant que le champ à ignorer n’est pas terminé et le sauve dans un fichier auxiliaire. Mais pour le MAC.

Function name : yylex Description : Analyseur Lexical d’un fichier RTF. Fournit les Tokens à yyparse. Function name : yyerror Description : Fonction de traitement des erreurs. Elle est apellée automatique- ment par yyparse, generée par Bision, lorsqu’une erreur s’est pro- duite. Si on est au sein de l’entête, on positionne le flag de présence de LaTEX. Si on est dans le corps du texte, on positionne le flag d’Erreur, pour que l’analyseur lexical ignore tout jusqu’au debut du prochain paragraphe.

Function name : main Description : Fonction Principale: Analyse les paramètres, ouvre les flux, et apelle yyparse().

2.0.2 rtf.formule.c

Function name : moulineFormule

Description : Après détection d’une formule, on la mouline de facon à rectifier les absurdités de formatage de RTF-Fields.

Function name : moulineFormuleMAC

Description : Après detection d’une formule MAC, on la mouline de facon à rectifier les absurdités de formatage de RTF-Fields. Mais pour le Mac.

2.0.3 rtf.fonts.c

Function name : nouvfonte Description : Crée un nouveau maillon avec la description d’une fonte Function name : cherchefonte Description : A partir du numéro de fonte, cherche une fonte donnée.

Function name : parcoursfontes

Description : fonction de debuggage. Function name : chercheEqTeX Description : Cherche un equivalent LaTEX pour un nom de fonte RTF Function name : EqTeXTaille Description : Détermine la taille de police à utiliser, à partir de la donnée RTF, et retourne la chaine de caractères équivalente TeX.

Function name : printSymbol Description : Imprime un Symbole, en fonction de l’environnement dans lequel on se trouve.

Function name : printText Description :

Function name : printApostrophe

Description :

2.0.4 rtf.context.c

Function name : nouvcontext Description : Crée un nouveau maillon contexte à partir de sa description et retourne un pointeur sur ce maillon

Function name : contextback Description :

Function name : parcourscontexts

Description : Parcours de la liste chainée de contextes. (Debuggage);

Function name : endkeepcontext

Description : Termine le contexte courrant mais le garde en tant que contexte courrant. Utile pour les Tableaux, car LaTEX impose de terminer les environnements avant de sortir de la minipage, alors que RTF ne le fait pas. A utiliser suivi immediatement de showcontext...

Function name : showcontext Description : Exprime les caracteristiques du contexte courrant. A utiliser en particulier pour les tableaux après endkeepcontext 2.0.5 rtf.ascii

Ce fichier contient les tables de correspondance ASCII entre MAC, PC et LaTEX.

2.0.6 rtf.fields.c

Function name : filtrefields Description : Recupère un champ field et le prépare à être analyse par yylex

2.0.7 rtf.output

Le fichier rtf.output est généré par Bison si on l’exécute avec l’option -v. Il détaille l’état de la grammaire et de ses règles. Les conflicts qui existent actuellement sont dus au fait que la grammaire RTF n’est pas LALR1. Ils ne devraient pas causer de problème. Lors de l’implémentattion de nouvelles règles, il faudra veiller à ce que ce nombre n’augmente pas.

2.0.8 rtf.tab.c

Il s’agit du fichier généré par Bison, et qui sera lui compilé pour obtenir l’exécutable. Pour le compiler:

>cc -o w2latex rtf.tab.c

et ça y est!

2.0.9 rtf.motcom.h

Ce fichier contient la table de correspondance entre les mots de commande RTF et les tokens. Il s’agit des mêmes mots, mais en majuscules. Lors de l’implémentation de nouvelles règles demandant de nouveaux tokens, il ne faut pas oublier de les répertorier ici (et d’augmenter le nombre des éléments du tableau défini dans l’entête du fichier.

3 Documents de Référence

– BISON: The Yacc compatible Parser Generator Bison Version 1.20 By Charles Donnelly and Richard Stallman

– A Gentle Introduction to TEX.

Michael Doob University of Manitoba

– Notes de Cous LaTEX.

Claude Gomez INRIA

– Essential LaTEX.

Jon Warbrick

– LaTEX: user’s guide and Reference Manual Leslie Lamport Addison-Wesley

– Microsoft Rich Text Format (RTF) Specification Microsoft\begin{matrix}c \\ ◯ \end{matrix} Application Note RTF VErsion 1.3 1994

– Fields Reference Microsoft\begin{matrix}c \\ ◯ \end{matrix} Word\begin{matrix}c \\ ◯ \end{matrix} Version 6.0

4 Disclaimer

Ce document se rapporte au programme W2LaTEX, réalisé par Javier Garmendia^{1}, et a été réalisé pour le Centre International de Rencontres Mathématiques de Luminy (Marseille), sous la direction de Jean-Louis Maltret^{2}.

1jgarmend@cyberspace.org

2jlm@cirm.univ-mrs.fr