OVH Cloud OVH Cloud

macro big pour latex

14 réponses
Avatar
Ph. Idlavi
Bonjour,

Une région contient, par exemple, le texte suivant :
((des commandes (des commandes (des commandes (des commandes )des
commandes )des commandes )des commandes) des commandes)

je voudrais la convertir en :
\Bigg(\bigg(des commandes \Big(des commandes \big(des commandes (des
commandes )des commandes \big)des commandes \Big)des commandes\bigg) des
commandes\Bigg)

Quelqu'un pourrait-il m'indiquer un début de code pour effectuer la
conversion ?
Je ne vois même pas par où commencer...

Merci de votre aide.
--
Philippe.

10 réponses

1 2
Avatar
Matthieu Moy
Ph. Idlavi writes:

je voudrais la convertir en :
Bigg(bigg(des commandes Big(des commandes big(des commandes (des
commandes )des commandes big)des commandes Big)des commandesbigg) des
commandesBigg)

Quelqu'un pourrait-il m'indiquer un début de code pour effectuer la
conversion ?



Je commencerai comme ça :

(defvar mm-big-list '("Bigg" "bigg" "Big" "big"))

(defun mm-replace (list)
(when list
(save-restriction
(let ((begin ...)
(end ...))
(narrow-to-region begin end)
...
(mm-replace (cdr list))))))

puis

(mm-replace mm-big-list)

Mais pourquoi ne pas utiliser left et right ?

--
Matthieu
Avatar
drkm
Matthieu Moy wrote:

(defvar mm-big-list '("Bigg" "bigg" "Big" "big"))

(defun mm-replace (list)
(when list
(save-restriction
(let ((begin ...)
(end ...))
(narrow-to-region begin end)
...
(mm-replace (cdr list))))))



L'idée du narrowing semblait intéressante, mais il faut alors
calculer plusieurs fois les bornes des sous-ensembles (le calcul de
'end', ci-dessus).

Une manière d'éviter cela serait de passer 'begin' en paramètre.
La fonction cherche alors la première '(' ou ')'. Si c'est ')', on ne
récurse pas. La fonction retourne 'end'. De manière à ce que celle
qui l'a appellée puisse continuer à partir de cette position. En
pseudo-code (je n'ai pas Emacs sous le coude) :

(defun mm-replace (begin list)
;; un peu trop simple
(interactive (list pos mm-big-list))
(let ((pos begin))
(while (and pos <- position du premier '(' ou ')' après 'pos'
char-at pos == '(')
;; que 'list' soit vide ou non, il faut sauter les sous-()
(setq pos (mm-replace pos (cdr list))))
;; 'pos' est sur le ')' associé au '(' de 'begin'
(when list
remplace ')' par (car list))
ajuste pos
pos))

Il manque bien sûr la gestion des erreurs et des situations
exceptionnelles.

--drkm
Avatar
Ph. Idlavi
Matthieu Moy écrivit le 08/11/05 à
16h09:34 :

Mais pourquoi ne pas utiliser left et right ?



Une expression du type :
$dfrac{r}{r'}(cos(theta+(-theta))+icos(theta+(-theta')))$
manque de lisibilité et ajouter des left right ne change rien
(caractères de hauteur standard).

Je préfère :
$dfrac{r}{r'}Big(cosbig(theta+(-theta)big)+icosbig(theta+(-theta')big)Big)$
mais c'est pénible à taper (et encore il n'y a que 3 niveau de
parenthèses).


J'étudie les deux propositions de code dès que j'ai le temps.

Merci pour votre aide.
--
Philippe.
Avatar
drkm
Ph. Idlavi wrote:

J'étudie les deux propositions de code dès que j'ai le temps.



Que dis-tu de ceci :

(defvar mm-big-list '("Bigg" "bigg" "Big" "big")
"À toi de jouer.")

(defun mm-replace (list)
"À tois de jouer."
(interactive (progn (search-forward "(") (list mm-big-list)))
(when list
(backward-char) (insert "" (car list)) (forward-char))
(while (and (search-forward-regexp "[()]")
(eq ?( (char-before)))
(mm-replace (cdr list)))
(when list
(backward-char) (insert "" (car list)) (forward-char)))

--drkm
Avatar
Prakash Countcham
Ph. Idlavi writes:
Mais pourquoi ne pas utiliser left et right ?



Une expression du type :
$dfrac{r}{r'}(cos(theta+(-theta))+icos(theta+(-theta')))$
manque de lisibilité et ajouter des left right ne change rien
(caractères de hauteur standard).

Je préfère :
$dfrac{r}{r'}Big(cosbig(theta+(-theta)big)+icosbig(theta+(-the ta')big)Big)$
mais c'est pénible à taper (et encore il n'y a que 3 niveau de
parenthèses).



C'est hors-sujet, mais je voulais signaler delimitershortfall et
delimiterfactor qui servent à ce genre de choses.

documentclass{article}
usepackage{amsmath}
begin{document}
[dfrac{r}{r'}Big(cosbig(theta+(-theta)big)+icosbig(theta+(-thet a')big)Big)]

setlength{delimitershortfall}{-1pt}

[dfrac{r}{r'}left(cosleft(theta+left(-thetaright)right) +
icosleft(theta+left(-theta'right)right)right)]
end{document}

Cordialement,

--
Prakash
Avatar
Ph. Idlavi
Prakash Countcham écrivit le 08/12/05 à 10h36:32 :

C'est hors-sujet, mais je voulais signaler delimitershortfall et
delimiterfactor qui servent à ce genre de choses.

[...]




Je ne connaissais pas. C'est intéressant.
Cependant, les délimiteurs ne sont plus de la même taille au niveau des
cosinus alors qu'il sont à la même profondeur.

--
Philippe.
Avatar
Prakash Countcham
Ph. Idlavi writes:
Je ne connaissais pas. C'est intéressant.
Cependant, les délimiteurs ne sont plus de la même taille au niveau d es
cosinus alors qu'il sont à la même profondeur.



C'était juste une remarque pour éventuellement faciliter l'écriture d e ton
document.

Les délimiteurs s'adaptent à la taille de leur contenu, et theta' n'a pas la
même taille que theta.

Amicalement,

--
Prakash
Avatar
Ph. Idlavi
"drkm" écrivit le 08/12/05 à 02h21:27 :


Que dis-tu de ceci :

(defvar mm-big-list '("Bigg" "bigg" "Big" "big")
"À toi de jouer.")

(defun mm-replace (list)
[...])




Je dis que c'est bien codé que ce que j'ai trouvé :

(defvar mm-big-liste '("big" "Big" "bigg" "Bigg"))
(defun big-paren-region (beginr endr)
(interactive "r")
(let ((list mm-big-liste))
(narrow-to-region beginr endr)
(goto-char beginr)
(when (re-search-forward "(*)" nil nil 1) ;; On se place à la profondeur maxi
(while (and list (re-search-forward "(*)" nil nil 1))
(backward-char 1)
(insert (car list))
(match-paren 1)
(insert (car list))
(match-paren 1)
(forward-char 1)
(setq list (cdr list))
))
(widen)
))

Les deux macro donnent le résultat escompté sur :
(des comm(des commandes (des commandes (des commandes (des
commandes )des commandes )des commandes )des commandes) des commandes)

à savoir :
Bigg(des commbigg(des commandes Big(des commandes big(des commandes
(des commandes )des commandes big)des commandes Big)des
commandesbigg) des commandesBigg)


En revanche, les choses sont plus compliquées que ce que je pensais :
* un M-x big-paren-region sur :
(a+(a+b)+(c+d)+e)+((a+b)+c)
donne :
Big(a+(a+b)+big(c+dbig)+eBig)+Bigg(bigg(a+bbigg)+cBigg)

* un M-x mm-replace sur :
(a+(a+b)+(c+d)+e)+((a+b)+c)
donne :
Bigg(a+bigg(a+bbigg)+bigg(c+dbigg)+eBigg)+((a+b)+c)

alors qu'il faudrait obtenir "simplement":
big(a+(a+b)+(c+d)+ebig)+big((a+b)+cbig)



Existe-t-il une macro qui retourne la profondeur des parenthèses où se
trouve le point?
Avec (a+b(c+d)+(e+(f+g)))
elle retournerait 1 si le point est sur a+b
2 si le point est sur c+d
3 si le point est sur f+g

Ceci dit, il faudrait peut-être que je poste sur fr.comp.text.tex. Il y
a peut-être une solution purement TeXienne...
Ou faire un "Cross-post" mais je ne sais pas faire.
--
Philippe.
Avatar
Ph. Idlavi
Prakash Countcham écrivit le 08/12/05 à 11h24:47 :

Ph. Idlavi writes:
Je ne connaissais pas. C'est intéressant.
Cependant, les délimiteurs ne sont plus de la même taille au niveau des
cosinus alors qu'il sont à la même profondeur.



C'était juste une remarque pour éventuellement faciliter l'écriture de ton
document.



Non seulement c'est une remarque judicieuse mais, en plus, j'ai appris
quelque chose. Je t'en remercie.
Je m'en servirais sûrement et l'adopterais définitivement si je ne
parviens pas à trouver la macro elisp adéquate.


Les délimiteurs s'adaptent à la taille de leur contenu, et theta' n'a pas la
même taille que theta.



Exact, je n'avais pas bien observé.


Amicalement,



Amicalement itou.
--
Philippe.
Avatar
drkm
Ph. Idlavi wrote:

Bonjour

Je crosse-poste sur f.c.algorithmes (depuis f.c.a.emacs), me rendant
compte après avoir rédigé mon article que ce dernier y avait
peut-être plus sa place. Je ne l'ai pas retouché, je pense que le
problème est clair pour quelqu'un qui débarque dans la discussion.
Juste un détail : il est à un moment question d'une liste de strings
; la voici : "Bigg", "bigg", "Big", "big".

* un M-x mm-replace sur :
(a+(a+b)+(c+d)+e)+((a+b)+c)
donne :
Bigg(a+bigg(a+bbigg)+bigg(c+dbigg)+eBigg)+((a+b)+c)

alors qu'il faudrait obtenir "simplement":
big(a+(a+b)+(c+d)+ebig)+big((a+b)+cbig)



Mmh. J'ai sans doute mal compris l'énoncé, alors. Je pensais
qu'il fallait partir de "Bigg" vers "big", en employant le premier au
premier niveau de parenthèses, le second au second niveau, etc. S'il
y avait trop de niveaux et que l'on avait épuisé la liste, on
ignorait les parenthèses.

Il semblerait plutôt qu'il faille partir du niveau le plus profond,
le laisser tel quel, puis parcourir la liste des macros dans l'autre
sens en remontant de niveau de profondeur. Donc :

() -> ()
(()) -> big(()big)
((())) -> Big(big(()big)Big)
(((()))) -> bigg(Big(big(()big)Big)bigg)
(()(())) -> Big(big(big)big(()big)Big)

Est-ce bien cela ? Notamment le dernier exemple. Si oui, ça
complique un peu les choses, mais il devrait y avoir moyen d'adapter
assez facilement le 'mm-replace' que je t'ai proposé.

Il faut garder la position des parenthèses du niveau courant. La
fonction retourne le niveau courant (0 = le plus profond). Lorsque
l'on est au niveau 0, on retourne 0. Sinon, on retourne le niveau
maximum des appels récursifs (donc des niveaux inférieurs) + 1.

Le problème, c'est que le niveau d'un sous-ensemble peut dépendre
d'un sous-ensemble disjoint. Dans le dernier exemple ci-dessus, le
premier '()' est au niveau 1. Mais on ne peut le savoir qu'après
avoir rencontré le second '()', qui lui est au niveau 0.

Mmh. En fait, je ne vois pas d'autre moyen que de procéder en deux
phases. La première dresse la carte des parenthèses, la seconde la
parcours par niveau et effectue les changements ad hoc.

Quelqu'un voit-il une autre solution ?

--drkm
1 2