Trouver le crochet fermant qui va avec le crochet ouvrant

Le
Laurent Claessens
Bonjour

Mon objectif est de parser un peu de code LaTeX. En particulier, je
voudrais obtenir une liste des macros utilisées et de leurs arguments.

Typiquement, si j'ai le code suivant :

+++++++++++++++ exemple ++++++++++

Bonjour, j'ulise la première macro macroUn{fooUn}{barUn} et puis
ma seconde macro macroDeux{fooDeux}{barDeux}{argument3} et encore une
fois la première macroUn{refooUn}{rebarUn}

+++++++++++++ fin d'exemple ++++++++

Mettons que le tout soit un string (y compris des sauts de ligne
éventuels).
Ce que je voudrais c'est obtenir les listes de tuples suivants

macroUn --> [ ("fooUn","barUn"),("refooUn","rebarUn") ]
macroDeux --> [ ("fooDeux","barDeux","argument3") ]

Le but est donc de parser le texte, repérer les occurrences de
macroUn et puis sortir un tuple (ou une liste) qui contient les
éléments entre {} situés derrière.


Sur le forum de LaTeX, on m'a proposé une expression rationnelle, mais
je préfère ne pas l'utiliser parce qu'a priori, je ne sais pas combien
d'arguments a une macro, donc je ne sais pas combien de paires {}
je dois chercher.

Évidemment, je vois plus ou moins comment faire ce que je veux à coups
de manipulations de chaines : si le code LaTeX est dans la chaine s,
je commence par s.split("macroUn") et puis je parcours les éléments
de la liste un par un en cherchant les occurrences de { et de }.

Est-ce qu'il existe une façon plus simple ? Par exemple, si je sais
que le caractère 37 d'une chaîne est un crochet ouvrant, est-ce que
python peut me dire où est le crochet fermant correspondant ?

merci pour toute idée éventuelle
bonne nuit
Laurent

PS1 : je suis en train de lire la doc de plasTeX, et je ne crois pas
que ça fasse ce que je veux encore que je n'y comprenne pas grand
chose ;)
PS2 : le contexte de ma question est ici :
[1] http://groups.google.fr/group/comp.text.tex/browse_thread/thread/3c6913=
dcd9c6634c#
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Paul Gaborit
Le #21010631
À (at) Tue, 19 Jan 2010 14:03:57 -0800 (PST),
Laurent Claessens
Mon objectif est de parser un peu de code LaTeX. En particulier, je
voudrais obtenir une liste des macros utilisées et de leurs arguments.

Typiquement, si j'ai le code suivant :

+++++++++++++++ exemple ++++++++++

Bonjour, j'ulise la première macro macroUn{fooUn}{barUn} et puis
ma seconde macro macroDeux{fooDeux}{barDeux}{argument3} et encore une
fois la première macroUn{refooUn}{rebarUn}

+++++++++++++ fin d'exemple ++++++++

Mettons que le tout soit un string (y compris des sauts de ligne
éventuels).
Ce que je voudrais c'est obtenir les listes de tuples suivants

macroUn --> [ ("fooUn","barUn"),("refooUn","rebarUn") ]
macroDeux --> [ ("fooDeux","barDeux","argument3") ]

Le but est donc de parser le texte, repérer les occurrences de
macroUn et puis sortir un tuple (ou une liste) qui contient les
éléments entre {...} situés derrière.



D'un point de vue (La)TeX, ces spécifications sont soit très
imprécises soit très limitatives... Que se passe-t-il lorsqu'une macro
est appelée comme argument d'une autre macro ? Que faites-vous des
arguments optionnels (entre crochets) ? Que faites-vous pour les
macros qui n'utilisent pas nécessairement les accolades comme
délimiteur (verb, centering ou let par exemple) ? Comment
espérez-vous découvrir le nombre d'arguments réellement attendus par
une macro ? Que faites-vous dans le cas où un argument contient
plusieurs niveaux d'accolades imbriqués ?

Sur le forum de LaTeX, on m'a proposé une expression rationnelle, mais
je préfère ne pas l'utiliser parce qu'a priori, je ne sais pas combien
d'arguments a une macro, donc je ne sais pas combien de paires {...}
je dois chercher.



On peut sans doute la généraliser pour une nombre quelconque
d'arguments mais l'expression rationnelle proposée ne gère pas
l'imbrication de macros ou de groupes entourés d'accolades...

--
Paul Gaborit -
Laurent Claessens
Le #21011701
>D'un point de vue (La)TeX, ces sp cifications sont soit tr s
impr cises soit tr s limitatives... Que se passe-t-il lorsqu'une macro
est appel e comme argument d'une autre macro ? Que faites-vous des
arguments optionnels (entre crochets) ? Que faites-vous pour les
macros qui n'utilisent pas n cessairement les accolades comme
d limiteur (verb, centering ou let par exemple) ? Comment
esp rez-vous d couvrir le nombre d'arguments r ellement attendus par
une macro ? Que faites-vous dans le cas o un argument contient
plusieurs niveaux d'accolades imbriqu s ?



Pour l'instant, je vais me contenter d'être très limitatif. Mes buts
sont au final les choses suivantes :

1. Vérifier quelles sont les macros défnies dans mon préambule qui
sont effectivement utilisées (pour ça, je n'ai même pas besoin des
arguments)
2. savoir quels sont les fichiers appelés avec input{...}, en
supposant qu'ils sont dans le répertoire courrant. Ici, l'objectif est
de générer un seul gros fichier tex qui contient tous les input
explicitement et de façon récursive.
3. Lire le fichier .aux d'un document LaTeX avec un script python.
J'écris un module en python dont le but est de générer du code pstric ks
[1], et je voudrais pourvoir utiliser, à l'intérieur du script python,
la valeur de certains compteurs internes à LaTeX. Pour cela, je compte
faire en deux compilations, avec écriture/lecture dans le
fichier .aux.
4. Pour ce même script, j'aimerais également que python soit capable
de récupérer la taille de certaines boites LaTeX (toujours via .aux),
affin de calculer la bounding box de la figure quand la figure
contient du texte. Ce dernier point fera l'objet d'une question sur le
forum de LaTeX ;)

Ce sont donc surtout à des lignes du style de celle-ci que je pense :
newlabel{MonLabel}{{4.1}{4}{Hello world!relax }{Item.3}{}

Je suis encore en train de lire la doc de plasTeX; je ne désespère pas
que ce module fasse le travail à ma place ...



Bonne journée
Laurent

[1] http://student.ulb.ac.be/~lclaesse/phystricks-doc.pdf
Eric Deveaud
Le #21012191
Laurent Claessens wrote:
Est-ce qu'il existe une façon plus simple ? Par exemple, si je sais
que le caractère 37 d'une chaîne est un crochet ouvrant, est-ce que
python peut me dire où est le crochet fermant correspondant ?



pas sur que python fasse ça tout seul comme un grand.

par compte une méthode simple et bourine permet de trouver les
occurences des couples ouvrants fermants.

un pile qu'on empile à l'ouverture et qu'on dépile à la
fermeture.

sinon voir du côté des parsing d'arbres, il y a pas mal de
choses.

Eric
Alain Ketterlin
Le #21012851
Laurent Claessens
[...]
Ce sont donc surtout à des lignes du style de celle-ci que je pense :
newlabel{MonLabel}{{4.1}{4}{Hello world!relax }{Item.3}{}



C'est un très bon exemple, parce que 1) les accolades ne sont pas
équilibrées (j'imagine que c'est un problème de copier-colle r), et 2) il
illustre parfaitement ce que dit Paul à la fin de son message : quelle
que soit la subtilité de l'expression régulière, tu ne peux pas capturer
une imbrication d'accolades de profondeur quelconque. C'est une
limitation fondamentale. Si tu cherches des macros particulières, de
forme particulière, alors tu peux utiliser des expressions réguli ères.

Le mieux que tu puisses faire dans le cas général est d'écri re une
grammaire, même approximative, de LaTeX. Il te faut alors un gén érateur
de parser. En python j'avais un peu joué avec pyparsing, qui me sembla it
plutôt bien. Bien sûr il y en a des tonnes (cf
http://wiki.python.org/moin/LanguageParsing). En plus, le générat eur n'a
pas besoin d'être écrit en python, à condition qu'il sache g énérer du
python.

Et tout cela en gardant en mémoire que seul TeX sait parser du TeX...

-- Alain.
alain31
Le #21013051
J'ai écrit un petit parser en pyparsing pour récupérer mes exercices
en LaTeX :
Structure :
begin{ex}
stuff
begin{sol}
stuff
end{sol}
end{ex}
Il ne m'a fallu qu'une heure pour apprendre à utiliser pyparsing et
obtenir une première version qui fonctionne. Le petit bouquin
O'Reilly sur pyparsing ainsi que le wiki sont très bien faits. Je te
recommande ce module !
http://pyparsing.wikispaces.com/
Alain.

Le mieux que tu puisses faire dans le cas général est d'écrire une
grammaire, même approximative, de LaTeX. Il te faut alors un généra teur
de parser. En python j'avais un peu joué avec pyparsing, qui me semblai t
plutôt bien. Bien sûr il y en a des tonnes (cfhttp://wiki.python.org/ moin/LanguageParsing). En plus, le générateur n'a
pas besoin d'être écrit en python, à condition qu'il sache géné rer du
python.

Et tout cela en gardant en mémoire que seul TeX sait parser du TeX...

-- Alain.


Publicité
Poster une réponse
Anonyme