1 Mercredi 3 Octobre 1984
INRIA
Domaine de Voluceau
Rocquencourt
78153 Le Chesnay Cedex
Vprint
Le Composeur Ceyx
Ge'rard Berry, Jean-Marie Hullot
Ete' 1984
Re'sume': ←N←o←u←s ←d←e'←f←i←n←i←s←s←o←n←s ←u←n←e ←m←a←c←h←i←n←e ←v←i←r←t←u←e←l←l←e ←p←e←r←m←e←t←t←a←n←t ←d←e
←p←r←o←d←u←i←r←e ←d←e←s ←r←e←p←r←e'←s←e←n←t←a←t←i←o←n←s ←t←e←x←t←u←e←l←l←e←s ←d←e ←s←t←r←u←c←t←u←r←e←s ←L←i←s←p ←o←u
←C←e←y←x ←a←r←b←i←t←r←a←i←r←e←s.
2 Mercredi 3 Octobre 1984
3 Mercredi 3 Octobre 1984
Vprint
Le Composeur Ceyx
←G←e'←r←a←r←d ←B←e←r←r←y, ←J←e←a←n-←M←a←r←i←e ←H←u←l←l←o←t
Nous de'finissons une machine pour composer Ceyx. Cette
documentation donne les fonctions de base de la machine et un
programme standard de paragraphage (pretty-print) utilisant cette
machine.
La lecture de ce document suppose une connaissance pre'alable de
Ceyx et Le←Lisp. Nous renvoyons pour cela aux rapports INRIA
suivants:
o+ Le←Lisp de l'INRIA, Le Manuel de Re'fe'rence (J. Chailloux),
o+ Ceyx: Une Initiation (J.-M. Hullot),
o+ Programmer en Ceyx (J.-M. Hullot).
1 La Machine de Composition
1.1 Impression des Atomes
(with-vprint-output <expr>1 ... <expr>n)
Les <expr>i sont des expressions Lisp quelconques qui sont
e'value'es en se'quence. Toutes les fonctions d'impression et de
composition de'crites ci-dessous ne fonctionnent que si elles
sont utilise'es dans le corps d'un with-vprint-output.
4 Mercredi 3 Octobre 1984
Vprint Le Composeur Ceyx
(vpatom <atom>)
Permet d'imprimer un atome Lisp quelconque.
(vprincn <charn>)
<charn> est un code ascii, cette fonction imprime le caracte`re
correspondant.
(vprinch <char>)
<char> est un symbole monocaracte`re qui est imprime'.
Exemples:
? (with-vprint-output (vprinch 'a))
a
= t
? (with-vprint-output (vprincn #/a))
a
= t
? (with-vprint-output (vpatom 'Celui) (vprinch '| |)
? (vpatom "qui") (vprinch '| |)
? (vpatom "sait") (vprinch '| |)
(vpatom "ne") (vprinch '| |)
(vpatom "parle") (vprinch '| |)
(vpatom "pas") (vprincn #/.) (vprinch '| |))
Celui qui sait ne parle pas.
= t
1.2 Les Blocs de Composition
Les fonctions de la section pre'ce'dente permettent de construire
des ←b←l←o←c←s ←d←e ←t←e←x←t←e monolignes. Pour l'exemple pre'ce'dent, nous
avons le bloc de texte:
*----------------------------*
5 Mercredi 3 Octobre 1984
Vprint Le Composeur Ceyx
|Celui qui sait ne parle pas.|
*----------------------------*
Dans le cas ou` ce bloc tient dans une ligne physique (i.e. sa
longueur est infe'rieure a` (rmargin)), il est imprime' tel que.
S'il ne tient pas dans une ligne, aucune indication n'est donne'e
sur la fac,on dont on doit le couper en plusieurs lignes lors de
l'impression. Nous dirons que les blocs de texte sont ←i←n←s←e'←c←a←b←l←e←s.
Nous donnons maintenant des constructions permettant de
structurer des blocs de manie`re a` autoriser l'impression sur
plusieurs lignes. Pour cela, nous introduisons les notions de
←p←o←i←n←t ←d←e ←c←o←u←p←u←r←e et de ←b←l←o←c ←d←e ←c←o←m←p←o←s←i←t←i←o←n.
(vcutpoint <atom>)
(vcutpoint)
Cette fonction introduit un point de coupure optionnel qui est
interpre'te' de manie`re diffe'rente dans le contexte d'un bloc
horizontal, vertical ou mixte (voir ci-dessous).
1.2.1 Les Blocs Horizontaux
(hblock <indent> <expr>1 ... <expr>n)
<indent> doit avoir pour valeur un entier. Les <expr>i sont
des expressions Lisp quelconques qui sont e'value'es en
se'quence. Cette fonction place la machine de composition en
mode horizontal.
(hblock 3
(vpatom "Celui")
(vcutpoint)
(vpatom "qui")
(vcutpoint)
(vpatom "sait") *----------------------------------------*
(vcutpoint) |*-----* *---* *----* *--* *-----* *----*|
(vpatom "ne") ||Celui|↑|qui|↑|sait|↑|ne|↑|parle|↑|pas.||
(vcutpoint) |*-----* *---* *----* *--* *-----* *----*|
6 Mercredi 3 Octobre 1984
Vprint Le Composeur Ceyx
(vpatom "parle") *----------------------------------------*
(vcutpoint)
(vpatom "pas")
(vprincn #/.))
En mode horizontal, les points de coupure sont interpre'te's comme
des espaces tant que la marge droite n'est pas atteinte, si aucun
argument n'est donne' a` vcutpoint. Si un argument <atom> est
donne', on imprime cet atome a` la place de l'espace. Ainsi si
toute l'expression tient sur la ligne, le re'sultat de
l'impression est:
Celui qui sait ne parle pas. |<-- rmargin
Dans le cas contraire, un saut de ligne est produit a` la place du
dernier point de coupure sur la ligne, et l'impression reprend a`
la ligne suivante avec le renfoncement <indent>:
Celui qui sait |<-- rmargin
ne parle pas.|
ou, avec une marge droite plus petite,
Celui qui |<-- rmargin
sait ne |
parle pas.|
Noter que dans ce cas le blanc ou la chai↑ne argument de
vcutpoint n'est pas imprime'.
{Vprint}:indent [variable]
La variable {Vprint}:indent contient la valeur par de'faut du
renfoncement. A l'initialisation du syste`me, elle vaut 3 et
elle peut bien sur e↑tre modifie'e par l'utilisateur.
7 Mercredi 3 Octobre 1984
Vprint Le Composeur Ceyx
1.2.2 Les Blocs Verticaux
(vblock <indent> <expr>1 ... <expr>n)
<indent> doit avoir pour valeur un entier. Les <expr>i sont
des expressions Lisp quelconques qui sont e'value'es en
se'quence. Cette fonction place la machine de composition en
mode vertical.
Avec l'exemple pre'ce'dent, dans lequel hblock est change' en
vblock,
(vblock 3 (vpatom "Celui") (vcutpoint) ...)
nous avons syste'matiquement la composition verticale suivante:
Celui
qui
sait
ne
parle
pas.
c'est a` dire que tous les points de coupure sont interpre'te's
comme des sauts de ligne.
1.2.3 Les Blocs Mixtes
(xblock <indent> <expr>1 ... <expr>n)
<indent> doit avoir pour valeur un entier. Les <expr>i sont
des expressions Lisp quelconques qui sont e'value'es en
se'quence. Cette fonction place la machine de composition en
mode mixte.
8 Mercredi 3 Octobre 1984
Vprint Le Composeur Ceyx
Reprenons l'exemple pre'ce'dent dans le cas d'un bloc mixte:
(xblock 3 (vpatom "Celui") (vcutpoint) ...)
Ici la composition se fait en mode horizontal si tout tient sur
une seule ligne et en mode vertical dans le cas contraire:
Celui qui sait ne parle pas |<-- rmargin
ou:
Celui |<-- rmargin
qui |
sait |
ne |
parle |
pas. |
Comme pre'ce'demment, (vcutpoint <atom>) imprime l'atome a` la place
du blanc en mode horizontal, et provoque un retour chariot sans
impression de l'atome en mode vertical. De plus un appel de
vcutpoint ne provoque pas de retour chariot si rien n'a e'te' e'crit
dans la ligne courante, afin d'e'viter la ligne blanche qui en
re'sulterait.
1.2.4 Exemples
Etant donne'e une liste d'atomes L, nous de'finissons la fonction
qui permet d'imprimer cette liste en inse'rant un point de coupure
entre chacun des e'le'ments de la liste:
Nous construisons deux listes que nous allons utiliser pour
visualiser le re'sultat de la composition. La premie`re liste L1
tient toujours sur une seule ligne, la liste L2 demande plusieurs
lignes pour s'imprimer:
9 Mercredi 3 Octobre 1984
Vprint Le Composeur Ceyx
? (setq L1 '(<item>1 <item>2 <item>3))
= (<item>1 <item>2 <item>3)
? (setq L2 '(<item>1 <item>2 <item>3 <item>4 <item>5 <item>6 <item>7 <item>8
? <item>9 <item>10 <item>11 <item>12 <item>13 <item>14 <item>15))
= (<item>1 <item>2 <item>3 <item>4 <item>5 <item>6 <item>7 <item>8 <item>9
<item>10 <item>11 <item>12 <item>13 <item>14 <item>15)
Nous nous plac,ons d'abord dans un mode de composition
horizontale:
? (with-vprint-output (hblock 0 (print-list-atoms L1)))
<item>1 <item>2 <item>3
= t
Les diffe'rents atomes apparaissent se'pare's par des espaces qui
sont l'interpre'tation des points de coupure dans ce cas.
Toujours en mode horizontal, mais dans le cas ou` une ligne ne
suffit pas pour l'impression, nous avons:
? (with-vprint-output (hblock 0 (print-list-atoms L2)))
<item>1 <item>2 <item>3 <item>4 <item>5 <item>6 <item>7 <item>8 <item>9
<item>10 <item>11 <item>12 <item>13 <item>14 <item>15
= t
L'atome <item>10 ne peut dans ce cas tenir sur la ligne; le point
de coupure entre <item>9 et <item>10 est alors interpre'te' comme
un saut de ligne, les autres continuant a` e↑tre interpre'te' comme
des espaces. Le renfoncement associe' au bloc horizontal vaut 0,
<item>10 commence en de'but de ligne. Nous donnons ci-dessous un
exemple avec un renfoncement non nul:
? (with-vprint-output (hblock 8 (print-list-atoms L2)))
<item>1 <item>2 <item>3 <item>4 <item>5 <item>6 <item>7 <item>8 <item>9
<item>10 <item>11 <item>12 <item>13 <item>14 <item>15
= t
10 Mercredi 3 Octobre 1984
Vprint Le Composeur Ceyx
Nous reprenons maintenant les me↑mes exemples dans un mode de
composition verticale:
? (with-vprint-output (vblock 0 (print-list-atoms L1)))
<item>1
<item>2
<item>3
= t
Dans ce cas, tous les points de coupure sont interpre'te's comme
des sauts de lignes. Avec un renfoncement non nul, nous avons:
? (with-vprint-output (vblock 3 (print-list-atoms L1)))
<item>1
<item>2
<item>3
= t
Enfin, dans le cas d'un mode de composition mixte, le mode de
composition horizontale est choisi si l'impression peut se faire
sur une seule ligne et le mode de composition verticale si une
ligne n'est pas suffisante:
? (with-vprint-output (xblock 0 (print-list-atoms L1)))
<item>1 <item>2 <item>3
= t
? (with-vprint-output (xblock 0 (print-list-atoms L2)))
<item>1
<item>2
<item>3
<item>4
<item>5
<item>6
<item>7
<item>8
<item>9
<item>10
<item>11
11 Mercredi 3 Octobre 1984
Vprint Le Composeur Ceyx
<item>12
<item>13
<item>14
<item>15
= t
Pour les initie's, remarquons que dans ce dernier mode il est
pre'fe'rable d'introduire un point de coupure de`s le de'but pour
e'viter les interfe'rences avec les blocs pre'ce'dents. La bonne
fac,on d'imprimer une liste en xblock est ainsi :
? (de print-list-atoms-xblock (l)
? (xblock 0
? (vcutpoint "")
? (vpatom (nextl l))
? (while l
? (vcutpoint)
? (vpatom (nextl l)))))
= print-list-atoms-xblock
1.3 Autres Commandes
(vterpri)
Cette fonction de'clenche un saut de ligne inconditionnel.
(vindent <indent>)
<indent> est un entier, cette fonction augmente le
renfoncement du bloc de composition courant de la valeur
<indent>.
(begin-hblock)
Cette fonction de'clenche l'ouverture d'un bloc horizontal qui
devra e↑tre ferme' ulte'rieurement par (end-block). La
construction hblock est de'finie a` l'aide de cette fonction
par:
(defmacro hblock (indent . body)
12 Mercredi 3 Octobre 1984
Vprint Le Composeur Ceyx
`(progn
(begin-hblock)
(vindent ,indent)
,@body
(end-block)))
(begin-vblock)
Identique a` la pre'ce'dente pour les blocs verticaux.
(begin-xblock)
Identique a` la pre'ce'dente pour les blocs mixtes.
(end-block)
Ferme un bloc de quelque nature qu'il soit.
2 Le Programme Standard d'Impression
En plus de la machine de composition pre'sente'e dans la section
pre'ce'dente, nous donnons un programme standard d'impression pour
les expressions Lisp et Ceyx. Au moment de l'e'criture de cette
documentation (Septembre 1984), le nombre de formats de
composition de'finis en standard n'est pas suffisant pour obtenir
un paragraphage ide'al de toutes les expressions Lisp. Ceci sera
comple'te' avec le temps.
2.1 Fonctions Ge'ne'rales
(vprint <expr> [profondeur])
Cette fonction re'alise un paragraphage (pretty-print) de
l'expression <expr>, jusqu'a` la profondeur donne'e en second
argument ou jusqu'a` la profondeur standard contenue dans la
variable {Vprint}:level (valant par de'faut (printlevel)). Ceci
signifie que l'impression s'arre↑te a` la profondeur dite, le
13 Mercredi 3 Octobre 1984
Vprint Le Composeur Ceyx
symbole # e'tant alors imprime' a` la place de la sous-expression
correspondante.
? (vprint '(a b c))
(a b c)
= t
? (vprint '((a b)(c d)))
((a b) (c d))
= t
? (vprint '((a b)(c d)) 1)
(# #)
= t
(vpretty <function-name> [profondeur])
Cette fonction re'alise le paragraphage (pretty-print) de la
fonction de nom <function-name>.
? (vpretty print-list-atoms)
(de print-list-atoms (l)
(vpatom (nextl l)) (while l (vcutpoint) (vpatom (nextl l))))
= t
2.2 Contro↑le du format d'impression par l'utilisateur
La fonction vprint peut e↑tre de'finie en Lisp par:
(de vprint (x)
(let ((x (car args))
({Vprint}:level (if (cadr args) (cadr args) {Vprint}:level)))
(with-vprint-output (vprin x))))
et c'est la fonction vprin qui se charge de la composition
suivant les cas.
14 Mercredi 3 Octobre 1984
Vprint Le Composeur Ceyx
(vprin <expr>)
Cette fonction se charge d'aiguiller la composition de
l'expression <expr>. Elle peut e↑tre de'finie en Lisp par:
(de vprin (x)
(let (({Vprint}:curlevel (1+ {Vprint}:curlevel)))
(if (> {Vprint}:curlevel {Vprint}:level)
(vprincn #/#)
(cond
((tconsp x) (sendq vprin x))
((null x) (vpatom "()"))
((stringp x) (vprincn #/") (vpatom x) (vprincn #/"))
((atom x) (vpatom x))
((consp x)
(if (symbolp (car x))
(selectq (ptype (car x))
(1 ({Vformat}:progn x))
(2 ({Vformat}:if x))
(3 ({Vformat}:defun x))
(4 ({Vformat}:cond x))
(5 ({Vformat}:selectq x))
(6 ({Vformat}:setq x))
(t (let ((vformat (getprop (car x) 'vformat)))
(ifn vformat
({Vformat}:data x)
(funcall vformat x)))))
({Vformat}:data x)))
(t (syserror 'vprin "Type Lisp Inconnu"))))))
Pour les objets atomiques, le comportement de cette fonction est
clair, nous nous attachons dans la suite au cas des objets qui
sont des tcons ou des cons.
2.2.1 Composition des Objets Tagge's (tcons)
Dans le cas ou` elle rencontre un objet tagge', la fonction vprin
envoie le message vprin a` l'objet en question.
15 Mercredi 3 Octobre 1984
Vprint Le Composeur Ceyx
De'finissons par exemple le Trecord toto par:
? (deftrecord toto a b c)
= toto
? (setq x (omakeq toto a 1 b 2 c 3))))
= #(toto 1 2 . 3)
Si nous ne de'finissons pas de se'mantique vprin pour toto, la
se'mantique vprin du mode`le * est re'cupe're'e, on obtient ainsi une
composition identique a` celle fournie par Le←Lisp:
? (vprint x)
#(toto 1 2 . 3)
= t
puisque {*}:vprin est de'fini par:
? (de {*}:vprin (x) (prin x))
= #:*:vprin
L'utilisateur peut changer ce format en rede'finissant la
se'mantique vprin pour le mode`le toto:
? (de {toto}:vprin (x)
? (vblock 3
? (vpatom 'toto)
? (vcutpoint)
? (vpatom "a: ")
? (vprin ({toto}:a x))
? (vcutpoint)
? (vpatom "b: ")
? (vprin ({toto}:b x))
? (vcutpoint)
? (vpatom "c: ")
? (vprin ({toto}:c x))))
= #:Model:Tmodel:toto:vprin
? (vprint x)
toto
16 Mercredi 3 Octobre 1984
Vprint Le Composeur Ceyx
a: 1
b: 2
c: 3
= t
2.2.2 Composition des Objets de Type Cons
Conforme'ment a` l'usage dans les pretty-printer Lisp, les objets
de type cons sont compose's suivant la valuer de leur car. Dans le
cas ou` ce car n'est pas un atome on appliquera le format par
de'faut (i.e. {Vformat}:data), sinon on regarde si un format n'a
pas e'te' attache' a` cet atome. Pour ce faire nous regardons tout
d'abord leur ptype a` la Le←Lisp et sinon nous regardons sur la
pliste de cet atome si une fonction de composition leur a e'te'
attache' sous la proprie'te' vformat.
Pour associer une fonction de composition a` un atome, nous
de'finissons la fonction deformat:
(deformat <symbol> (<arg>) . <body>))
Cette construction de'finit la fonction {Vformat}:<symbol>, et
attache le symbole {Vformat}:symbol sur la pliste de <symbol>
sous l'indicateur vformat de manie`re a` ce qu'il puisse e↑tre
re'cupe're' par vprin:
(de {Vformat}:symbol (<arg>) ,@<body>)
Dans le cas ou` l'appel a` la forme (deformat <symbol>1 <symbol>2)
{Vformat}:<symbol>2 est attache' a` <symbol>1 sous l'indicateur
vformat.
Exemples:
Le format standard est de'fini par:
(deformat data (l)
17 Mercredi 3 Octobre 1984
Vprint Le Composeur Ceyx
(hblock 1 (vprincn #/() (vplist l) (vprincn #/))))
Le format 'progn' est de'fini par (nous rappelons que la variable
{Vprint}:indent contient un entier qui est le renfoncement par
de'faut):
(deformat progn (l)
(xblock {Vprint}:indent
(vprincn #/()
(vplist l)
(vprincn #/))))
ou` vplist est de'finie par:
(vplist <lexpr>)
(de vplist (l)
(vprin (nextl l))
(while (consp l) (vcutpoint) (vprin (nextl l)))
(when l
(vcutpoint)
(vprincn #/.)
(vcutpoint)
(vprin l)))
Le format 'setq' est de'fini par:
(deformat setq (l)
(xblock {Vprint}:indent
(vprincn #/()
(vprin (nextl l))
(while l
(vcutpoint)
(xblock 2
(vprin (nextl l))
(vcutpoint)
(vprin (nextl l))))
(vprincn #/))))
18 Mercredi 3 Octobre 1984
Vprint Le Composeur Ceyx
Nous aurons ainsi:
? (rmargin 79)
= 79
? (vprint '(a b c d e f g h i j))
(a b c d e f g h i j)
= t
? (vprint '(progn a b c d e f g h i j))
(progn a b c d e f g h i j)
= t
? (vprint '(setq a 1 b 2 c 3 d 4 e 5))
(setq a 1 b 2 c 3 d 4 e 5)
= t
? (rmargin 10)
= 10
? (vprint '(a b c d e f g h i j))
(a b c d e
f g h i j)
= t
? (vprint '(progn a b c d e f g h i j))
(progn
a
b
c
d
e
f
g
h
i
j)
= t
? (vprint '(setq a 1 b 2 c 3 d 4 e 5))
(setq
a 1
b 2
c 3
d 4
e 5)
= t
19 Mercredi 3 Octobre 1984
Vprint Le Composeur Ceyx
20 Mercredi 3 Octobre 1984
Table des matie`res
1 Mercredi 3 Octobre 1984
Table des matie`res
Table des matie`res
1 La Machine de Composition..............................4
1.1 Impression des Atomes................................4
1.2 Les Blocs de Composition.............................5
1.2.1 Les Blocs Horizontaux..............................6
1.2.2 Les Blocs Verticaux................................8
1.2.3 Les Blocs Mixtes...................................8
1.2.4 Exemples...........................................9
1.3 Autres Commandes....................................12
2 Le Programme Standard d'Impression....................13
2.1 Fonctions Ge'ne'rales.................................13
2.2 Contro↑le du format d'impression par l'utilisateur...14
2.2.1 Composition des Objets Tagge's (tcons).............15
2.2.2 Composition des Objets de Type Cons...............17
2 Mercredi 3 Octobre 1984
Index des fonctions Lisp
1 Mercredi 3 Octobre 1984
Index des fonctions Lisp
Index des fonctions Lisp
(begin-hblock) .........................................12
(begin-vblock) .........................................13
(begin-xblock) .........................................13
(deformat <symbol> (<arg>) . <body>)) ..................17
(end-block) ............................................13
(hblock <indent> <expr>1 ... <expr>n) ...................6
(vblock <indent> <expr>1 ... <expr>n) ...................8
(vcutpoint <atom>) ......................................6
(vcutpoint) .............................................6
(vindent <indent>) .....................................12
(vpatom <atom>) .........................................5
(vplist <lexpr>) .......................................18
(vpretty <function-name> [profondeur]) .................14
(vprin <expr>) .........................................15
(vprinch <char>) ........................................5
(vprincn <charn>) .......................................5
(vprint <expr> [profondeur]) ...........................13
(vterpri) ..............................................12
(with-vprint-output <expr>1 ... <expr>n) ................4
(xblock <indent> <expr>1 ... <expr>n) ...................8
{Vprint}:indent [variable] ..............................7
2 Mercredi 3 Octobre 1984