Étude de l'exemple “mycas” |
La meilleure façon d'implémenter votre première interface avec TeXmacs est d'examiner soigneusement l'exemple mycas, que vous trouverez dans le répertoire $TEXMACS_PATH/misc/mycas. Le fichier mycas.cpp, dont le contenu est inclus à la fin de cette section, contient un programme très simple que l'on peut interfacer avec TeXmacs. Pour tester ce programme, compilez-le avec :
g++ mycas.cpp -o mycas
et déplacez le fichier binaire mycas obtenu
dans un répertoire connu de la variable d'environnement
système PATH. Quand vous démarrerez TeXmacs, un nouvel
article
NdT: Si vous utilisez le port Fink de TeXmacs, le plus simple est de copier le fichier mycas.cpp, situé dans le répertoire /sw/share/TeXmacs.../plugins/mycas/examples, dans ~/bin (créez le répertoire auparavant s'il n'existe pas déjà), puis compilez-le comment indiqué ci-dessus.
Étudions le code source de mycas pas à pas. Tout d'abord, toutes les communications se font via les entrées et sorties standards à l'aide de tubes. Pour permettre à TeXmacs de savoir quand les sorties système sont terminées, toutes les sorties doivent être encapsulées dans des blocs contenant trois caractères de contrôle spéciaux :
#define DATA_BEGIN ((char) 2)
#define DATA_END ((char) 5)
#define DATA_ESCAPE ((char) 27)
Le caractère DATA_ESCAPE suivi de n'importe quel autre caractère c est utilisé pour générer c, y compris dans le cas où c est l'un des trois caractères de contrôle mentionnés ci-dessus. Le message affiché au démarrage de la session montre comment utiliser DATA_BEGIN et DATA_END :
int
main () {
cout << DATA_BEGIN << "verbatim:";
cout << "–––––––––––––––––––––––––––\n";
cout << "Welcome to my test computer algebra system for TeXmacs\n";
cout << "This software comes with no warranty whatsoever\n";
cout << "(c) 2001 by Joris van der Hoeven\n";
cout << "–––––––––––––––––––––––––––\n";
next_input ();
cout << DATA_END;
fflush (stdout);
La première ligne du main stipule que le
message de démarrage sera imprimé en format
«
La boucle principale commence par demander une saisie à partir de l'entrée standard :
while (1) {
char buffer[100];
cin >> buffer;
if (strcmp (buffer, "quit") == 0) break;
La sortie générée doit de nouveau figurer dans un bloc DATA_BEGIN-DATA_END.
cout << DATA_BEGIN << "verbatim:";
cout << "You typed " << buffer << "\n";
À l'intérieur de ce type de bloc, on peut envoyer récursivement d'autre blocs qui peuvent utiliser des formats différents. Par exemple, le code suivant envoie une formule LaTeX :
cout << "And now a LaTeX formula: ";
cout << DATA_BEGIN << "latex:" << "$x^2+y^2=z^2$" << DATA_END;
cout << "\n";
Dans certains cas, il peut être utile d'envoyer directement la
sortie en format TeXmacs en utilisant une représentation
cout << "And finally a fraction ";
cout << DATA_BEGIN << "scheme:" << "(frac \"a\" \"b\")" << DATA_END;
cout << ".\n";
À la fin, il faut de nouveau envoyer DATA_END et vider la sortie standard :
next_input ();
cout << DATA_END;
fflush (stdout);
}
return 0;
}
Notez qu'il ne faut jamais envoyer plus d'un bloc DATA_BEGIN-DATA_END. Dès que le premier bloc DATA_BEGIN-DATA_END est reçu par TeXmacs, le système se met en attente d'entrée. Si vous voulez envoyer plusieurs blocs DATA_BEGIN-DATA_END, vous devez les inclure dans un bloc principal.
Un «
static int counter= 0;
void
next_input () {
counter++;
cout << DATA_BEGIN << "channel:prompt" << DATA_END;
cout << "Input " << counter << "] ";
}
À l'intérieur d'un canal d'invite, vous pouvez aussi utiliser des blocs DATA_BEGIN-DATA_END imbriqués. Ceci permet, par exemple, d'utiliser une formule comme invite. Il existe trois canaux standards :
On peut envoyer des images PostScript en sortie. À supposer qu'il existe une image picture.ps dans votre répertoire utilisateur, si vous insérez les lignes suivantes :
cout << "A little picture:\n";
cout << DATA_BEGIN << "ps:";
fflush (stdout);
system ("cat $HOME/picture.ps");
cout << DATA_END;
cout << "\n";
à l'endroit approprié dans la boucle principale, votre image s'affichera dans la sortie.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream.h>
#define DATA_BEGIN ((char) 2)
#define DATA_END ((char) 5)
#define DATA_ESCAPE ((char) 27)
static int counter= 0;
void
next_input () {
counter++;
cout << DATA_BEGIN << "channel:prompt" << DATA_END;
cout << "Input " << counter << "] ";
}
int
main () {
cout << DATA_BEGIN << "verbatim:";
cout << "–––––––––––––––––––––––––––\n";
cout << "Welcome to my test computer algebra system for TeXmacs\n";
cout << "This software comes with no warranty whatsoever\n";
cout << "(c) 2001 by Joris van der Hoeven\n";
cout << "–––––––––––––––––––––––––––\n";
next_input ();
cout << DATA_END;
fflush (stdout);
while (1) {
char buffer[100];
cin >> buffer;
if (strcmp (buffer, "quit") == 0) break;
cout << DATA_BEGIN << "verbatim:";
cout << "You typed " << buffer << "\n";
cout << "And now a LaTeX formula: ";
cout << DATA_BEGIN << "latex:" << "$x^2+y^2=z^2$" << DATA_END;
cout << "\n";
cout << "And finally a fraction ";
cout << DATA_BEGIN << "scheme:" << "(frac \"a\" \"b\")" << DATA_END;
cout << ".\n";
next_input ();
cout << DATA_END;
fflush (stdout);
}
return 0;
}