1 % $Id: dcpic.sty,v 1.31 2007/12/13 17:34:57 pedro Exp pedro $
3 %% Copyright (c) 1990-2007 Pedro Quaresma de Almeida, Coimbra
4 %% 11/1990 (version 1.0);
5 %% 10/1991 (version 1.1);
6 %% 9/1993 (version 1.2);
7 %% 3/1995 (version 1.3);
8 %% 7/1996 (version 2.1);
9 %% 5/2001 (version 3.0);
10 %% 11/2001 (version 3.1);
11 %% 1/2002 (version 3.2)
12 %% 5/2002 (version 4.0);
13 %% 3/2003 (version 4.1);
14 %% 12/2004 (version 4.1.1)
15 %% 3/2007 (version 4.1.2)
17 \immediate\write10{Package DCpic
2007/
03/
01 v4.1
.2}
19 \ProvidesPackage{../dcpic
}[2007/
03/
01 v4.1
.2]
24 %% Z - bug corrections
26 %% Copyright (c) 1990-2007 Pedro Quaresma <pedro@mat.uc.pt>
27 %% The DCpic package is free software; you can redistribute it and/or
28 %% modify it under the terms of the GNU General Public License as
29 %% published by the Free Software Foundation; either version 2 of the
30 %% License, or (at your option) any later version.
32 %% The DCpic package is distributed in the hope that it will be
33 %% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
34 %% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35 %% General Public License for more details.
37 %% You should have received a copy of the GNU General Public License
38 %% along with this package; if not, write to the Free Software
39 %% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42 \catcode`!=
11 % ***** THIS MUST NEVER BE OMITTED (Ver PiCTeX)
65 %% "variáveis globais"
67 \newcount\tipografo% versão 4.0
68 \newcount\distanciaobjmor% versão 4.0
69 \newcount\tipoarco% versão 4.0
70 %\newif\ifarredondada% versão 4.0 (valor inicial "false")
96 %% Stack specification
105 %% Is Empty? : Stack -> Bool
107 %% nvazia - True if Not Empy
108 %% vazia - True if Empty
109 \def\!pilhanvazia
#1{\let\arg=
#1%
110 \if:
\arg\
\nvaziafalse\vaziatrue \else \nvaziatrue\vaziafalse\fi}
113 %% Push : Elems x Stack -> Stack
115 \def\!coloca
#1#2{\edef\pilha{#1.
#2}}
118 %% Top : Stack -> Elems
120 %% the empty stack is not taken care
121 %% the element is "kept" ("guardado")
122 \def\!guarda(
#1)(
#2,
#3)(
#4,
#5,
#6)
{\def\id{#1}%
130 \def\!topaux
#1.
#2:
{\!guarda
#1}
131 \def\!topo
#1{\expandafter\!topaux
#1}
134 %% Pop : Stack -> Stack
136 %% the empty stack is not taken care
137 \def\!popaux
#1.
#2:
{\def\pilha{#2:
}}
138 \def\!retira
#1{\expandafter\!popaux
#1}
141 %% Compares words : Word x Word -> Bool
143 %% compara - True if equal
144 %% diferentes - True if not equal
145 \def\!comparaaux
#1#2{\let\argA=
#1\let\argB=
#2%
146 \ifx\argA\argB\comparatrue\diferentesfalse\else\comparafalse\diferentestrue\fi}
148 \def\!compara
#1#2{\!comparaaux
{#1}{#2}}
151 %% Valor absoluto (absolute value)
152 %% \absoluto{n}{absn}
156 %% absn - o valor absoluto de n
157 \def\!absoluto
#1#2{\n=
#1%
166 %% Name definitions for edge types and directions
172 \def\injectionarrow{5}
173 \def\aplicationarrow{6}
174 \def\surjectivearrow{7}
175 %% Name definitions for edge label placement
178 %% Tip direction for curved edges
189 %% Posicionamento da etiquetas nos grafos
203 %% Ajusta a dist{\^a}ncia entre as setas e os objectos em fun{\c c}{\~a}o das
204 %% dimens{\~o}es destes {\'u}ltimos
205 %% \ajusta{x}{xl}{y}{yl}{d}{Objecto}
207 %% (x,y) e (xl,yl), coordenadas dos pontos de {\'\i}nicio e fim da seta
208 %% d, dist{\^a}ncia especificada pelo utilizador ou 10 (valor por
209 %% omiss{\~a}o), Objecto d{\'a}-nos a refer{\^e}ncia do objecto ao qual se est{\'a} a
210 %% efectuar o ajuste.
212 %% d, dist{\^a}ncia alterada.
214 %% A dist{\^a}ncia alterada {\'e} o maior valor entre 10 e as dimens{\~o}es
215 %% apropriadas da caixa que cont{\^e}m o objecto.
216 %% Se o utilizador especificar um valor essa especifica{\c c}{\~a}o
217 %% n{\~a}o {\'e} alterada.
219 %% Se a seta {\'e} horizontal usa-se o valor da largura
220 %% Se a seta {\'e} vertical usa-se:
221 %% o valor da altura se a seta est{\'a} no 1o ou 2o quadrante
222 %% o valor da profundidade se a seta est{\'a} no 3o ou 4o quadrante
223 %% Se a seta {\'e} {\'o}bliqua vai-se escolher o valor conforme:
224 %% de 315 a 45 graus usa-se a largura
225 %% de 45 a 135 graus usa-se a altura
226 %% de 135 a 225 graus usa-se a largura
227 %% de 225 a 315 graus usa-se a profundidade
228 \def\!ajusta
#1#2#3#4#5#6{\aux=
#5%
230 \ifcase \tipografo % diagramas comutativos
232 \ajustadisttrue % se o valor é o valor por omissão ajusta
234 \ajustadistfalse % caso contrário não ajusta
236 \else % grafos (dirigidos, não dirigidos, com molduras)
238 % \or % grafos não dirigidos
240 % \else % grafos dirigidos com molduras circulares nos objectos
241 % \ifnum\number\aux=8
242 % \ajustadisttrue % se o valor é o valor por omissão ajusta
244 % \ajustadistfalse % caso contrário não ajusta
248 % \tiny Vou ajustar %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249 % \ifnum\number\aux=10% verificar se s{\~a}o os valores por omiss{\~a}o
250 \let\pilhaaux=
\pilha%
254 \!compara
{\id}{\auxobj}%
255 \ifcompara\nvaziafalse \else\!pilhanvazia
\pilha \fi%
258 %% rep{\~o}e os valores na pilha
259 \let\pilha=
\pilhaaux%
263 %% N{\~a}o {\'e} poss{\'\i}vel efectuar o ajuste dado o utilizador n{\~a}o ter
264 %% especificado uma etiqueta para o objecto em quest{\~a}o. {\'E} dado o
265 %% valor de 10, igual ao valor por omiss{\~a}o.
267 \larg=
1310720% n{\~a}o faz o ajuste
272 \divide\larg by
131072
273 \divide\prof by
65536
275 \ifnum\number\y=
\number\yl
276 %% Caso 1 -- seta horizontal
278 %% divide-se por 131072 para se obter metade da largura da caixa em
279 %% pontos (pt), isto dado que o texto est{\'a} centrado na caixa. Soma-se
280 %% mais tr{\^e}s, que constitue um ajuste imp{\'\i}rico.
282 \ifnum\number\larg>
\aux
286 \ifnum\number\x=
\number\xl
287 \ifnum\number\yl>
\number\y
288 %% Caso 2.1 -- seta vertical de cima para baixa
290 \ifnum\number\alt>
\aux
294 %% Caso 2.2 -- seta vertical de baixo para cima
296 %% divide-se por 65536 para se obter a altura da caixa em pt. O ajuste
297 %% de 5 foi obtido imp{\'\i}ricamente
299 \ifnum\number\prof>
\aux
304 %% Caso 3 -- seta obl{\'\i}qua
305 %% Caso 3.1 de 315o a 45o; |x-xl|>|y-yl| e
306 %% Caso 3.3 de 135o a 225o; |x-xl|>|y-yl|; Largura
308 \advance\auxqx by -
\xl
309 \!absoluto
{\auxqx}{\auxqx}%
311 \advance\auxqy by -
\yl
312 \!absoluto
{\auxqy}{\auxqy}%
320 %% Caso 3.2 de 45o a 135o; |x-xl|<|y-yl| e y>0; Largura
328 %% Caso 3.4 de 225o a 315o; |x-xl|<|y-yl| e y<0; Profundidade
335 \fi} % o ramo "else" {\'e} omisso
339 %% C{\'a}lculo da Raiz Quadrada
345 %% m - maior natural contido na raiz quadrada de n
346 \def\!raiz
#1#2{\n=
#1%
351 \multiply \aux by
\aux%
366 %% Calcula os pontos de
367 %% come{\c c}o da "seta"
369 %% coloca{\c c}{\~a}o do s{\'\i}mbolo
371 %% ucoord{x1}{x2}{x3}{x4}{x5}{x6}{+|- 1}
378 %% x6 = x3 +|- ------- x4
380 \def\!ucoord
#1#2#3#4#5#6#7{\aux=
#2%
381 \advance \aux by -
#1%
382 \multiply \aux by
#4%
384 \ifnum #7 = -
1 \multiply \aux by -
1 \fi%
389 %% C{\'a}lculo do Quadrado da Dist{\^a}ncia Euclidiana entre dois pontos
396 \def\!quadrado
#1#2#3{\aux=
#1%
397 \advance \aux by -
#2%
398 \multiply \aux by
\aux%
402 %% C{\'a}lculo auxiliar para determinar a dist{\^a}ncia entre o nome do
403 %% morfismo e a seta.
405 %% (x,y), (x',y') e o nome do morfismo
407 %% dnm - dist{\^a}ncia do nome ao morfismo respectivo devidamente
408 %% compensada pelo tamanho do objecto
409 %% Observa{\c c}{\~o}es
410 %% A compensa{\c c}{\~a}o s{\'o} est{\'a} a ser feita para setas
411 %% horizontais e verticais. As obl{\'\i}quas s{\~a}o tratadas de
414 %% caixa0 <- nome do morfismo
415 %% se x-xl = 0 entao {recta vertical}
416 %% aux <- largura da caixa0
417 %% dnm <- convers{\~a}o-sp-pt(aux)/2+3
418 %% sen{\~a}o {recta n{\~a}o vertical}
419 %% se y-yl = 0 entao {recta horizontal}
420 %% aux <- altura+profundidade da caixa0
421 %% dnm <- convers{\~a}o-sp-pt(aux)/2+3
422 %% sen{\~a}o {recta obl{\'\i}qua}
427 \def\!distnomemor
#1#2#3#4#5#6{\setbox0=
\hbox{#5}%
431 \aux=
\wd0 \divide \aux by
131072
438 \aux=
\ht0 \advance \aux by
\dp0 \divide \aux by
131072
449 %% O ambiente "begindc...enddc"
451 \def\begindc#1{\!ifnextchar
[{\!begindc
{#1}}{\!begindc
{#1}[30]}}
452 \def\!begindc
#1[#2]{\beginpicture
454 \setcoordinatesystem units <
1pt,
1pt>
459 \tipografo=
0 % diagrama comutativo
463 \tipografo=
1 % grafo orientado
467 \tipografo=
2 % grafo não orientado
471 \tipografo=
3 % grafo orientado
472 % \arredondadotrue % objectos com molduras circulares
476 \tipografo=
4 % grafo não orientado
477 % \arredondadotrue % objectos com molduras circulares
480 \def\enddc{\endpicture}
484 %% Comando para construir a "seta" entre dois objectos
486 %% Os pontos definidores da seta e da etiqueta respectiva s{\~a}o:
491 %% o------o---------o---------o------o
492 %%(x,y) (xa,ya) (xm,ym) (xb,yb)(xl,yl)
495 \!ifnextchar(
{\!morxy
}{\!morObjA
}}
497 \!ifnextchar(
{\!morxyl
{#1}{#2}}{\!morObjB
{#1}{#2}}}
498 \def\!morxyl
#1#2(
#3,
#4)
{%
499 \!ifnextchar
[{\!mora
{#1}{#2}{#3}{#4}}{\!mora
{#1}{#2}{#3}{#4}[\number\distanciaobjmor,
\number\distanciaobjmor]}}%
501 \let\pilhaaux=
\pilha%
506 \!compara
{\id}{\objPartida}%
507 \ifcompara \nvaziafalse \else \!pilhanvazia
\pilha \fi%
513 %% Mensagem de erro e atribui{\c c}{\~a}o de valores fict{\'\i}cios aos
514 %% argumentos dos comandos que se seguem.
516 Error: Incorrect label specification
%
521 \let\pilha=
\pilhaaux%
522 \!ifnextchar(
{\!morxyl
{\number\xaux}{\number\yaux}}{\!morObjB
{\number\xaux}{\number\yaux}}}
523 \def\!morObjB
#1#2#3{%
527 \let\pilhaaux=
\pilha%
531 \!compara
{\id}{\objChegada}%
532 \ifcompara \nvaziafalse \else \!pilhanvazia
\pilha \fi
538 %% Mensagem de erro e atribui{\c c}{\~a}o de valores fict{\'\i}cios aos
539 %% argumentos dos comandos que se seguem.
541 Error: Incorrect label specification
549 \!ifnextchar
[{\!mora
{\number\x}{\number\y}{\number\xaux}{\number\yaux}}{\!mora
{\number\x}{\number\y}{\number\xaux}{\number\yaux}[\number\distanciaobjmor,
\number\distanciaobjmor]}}
550 \def\!mora
#1#2#3#4[#5,
#6]#7{%
551 \!ifnextchar
[{\!morb
{#1}{#2}{#3}{#4}{#5}{#6}{#7}}{\!morb
{#1}{#2}{#3}{#4}{#5}{#6}{#7}[1,
\number\tipoarco] }}
552 \def\!morb
#1#2#3#4#5#6#7[#8,
#9]{\x=
#1%
556 \multiply \x by
\expansao%
557 \multiply \y by
\expansao%
558 \multiply \xl by
\expansao%
559 \multiply \yl by
\expansao%
561 %% calcular a dist{\^a}ncia Euclidiana entre dois pontos
562 %% d = \sqrt((x-xl)^2+(y-yl)^2)
564 \!quadrado
{\number\x}{\number\xl}{\auxa}%
565 \!quadrado
{\number\y}{\number\yl}{\auxb}%
567 \advance \d by
\auxb%
570 %% o ponto (xa,ya) est{\'a} {\`a} dist{\^a}ncia #5 (valor por omiss{\~a}o 10) do ponto
573 %% como existem dois pontos em considera{\c c}{\~a}o, o ponto de partida e o
574 %% ponto de chegada, vai sei necess{\'a}rio recuperar de novo os seus
575 %% valores por pesquisa na pilha
577 \!compara
{\objNulo}{\objPartida}%
578 \ifdiferentes% S{\'o} vai fazer o ajuste quando {\'e} necess{\'a}rio
579 \!ajusta
{\x}{\xl}{\y}{\yl}{\auxa}{\objPartida}%
581 \def\objPartida{}% re-inicializar o valor do Objecto de Partida
583 %% vai guardar o valor de auxa (ap{\'o}s ajuste) para ser usado no caso
584 %% dos morfismos de injec{\c c}{\~a}o.
587 \!ucoord
{\number\x}{\number\xl}{\number\x}{\auxa}{\number\d}{\xa}{1}%
588 \!ucoord
{\number\y}{\number\yl}{\number\y}{\auxa}{\number\d}{\ya}{1}%
589 %% auxa vai ter o valor da dist{\^a}ncia entre os objectos menos a
590 %% dist{\^a}ncia da seta ao objecto (10 por omiss{\~a}o)
593 %% o ponto (xb,yb) est{\'a} {\`a} dist{\^a}ncia #6 (valor por omiss{\~a}o 10) do ponto
597 \!compara
{\objNulo}{\objChegada}%
598 \ifdiferentes% S{\'o} vai fazer o ajuste quando {\'e} necess{\'a}rio
600 \!ajusta
{\x}{\xl}{\y}{\yl}{\auxb}{\objChegada}%
601 \def\objChegada{}% re-inicializar o valor do Objecto de Chegada
603 \advance \auxa by -
\auxb%
604 \!ucoord
{\number\x}{\number\xl}{\number\x}{\number\auxa}{\number\d}{\xb}{1}%
605 \!ucoord
{\number\y}{\number\yl}{\number\y}{\number\auxa}{\number\d}{\yb}{1}%
607 \advance \xmed by
\xb%
610 \advance \ymed by
\yb%
614 \!distnomemor
{\number\x}{\number\y}{\number\xl}{\number\yl}{#7}{\dnm}%
615 \!ucoord
{\number\y}{\number\yl}{\number\xmed}{\number\dnm}{\number\d}{\xc}{-
#8}%
616 \!ucoord
{\number\x}{\number\xl}{\number\ymed}{\number\dnm}{\number\d}{\yc}{#8}%
617 \ifcase #9 % Seta S{\'o}lida
618 \arrow <
4pt>
[.2,
1.1] from
{\xa} {\ya} to
{\xb} {\yb}
619 \or % Seta a Tracejado
621 \arrow <
4pt>
[.2,
1.1] from
{\xa} {\ya} to
{\xb} {\yb}
623 \or % Linha S{\'o}lida
625 \plot {\xa} {\ya} {\xb} {\yb} /
626 \or % Linha Tracejado
629 \plot {\xa} {\ya} {\xb} {\yb} /
631 \or % Linha a Ponteado
634 \plot {\xa} {\ya} {\xb} {\yb} /
636 \or % Seta de Injec{\c c}{\~a}o
637 %% C{\'a}lculos auxiliares
639 %% 3 valor para o raio do "rabo" da "seta"
641 %% repor o valor de auxa
643 %% dar a compensa{\c c}{\~a}o para o "rabo"
646 %% IMPORTANTE os valores de xa e ya v{\~a}o ser alterados
648 \!ucoord
{\number\x}{\number\xl}{\number\x}{\number\auxa}{\number\d}{\xa}{1}%
649 \!ucoord
{\number\y}{\number\yl}{\number\y}{\number\auxa}{\number\d}{\ya}{1}%
650 \!ucoord
{\number\y}{\number\yl}{\number\xa}{3}{\number\d}{\xd}{-
1}%
651 \!ucoord
{\number\x}{\number\xl}{\number\ya}{3}{\number\d}{\yd}{1}%
652 %% Constru{\c c}{\~a}o da "seta"
653 \arrow <
4pt>
[.2,
1.1] from
{\xa} {\ya} to
{\xb} {\yb}
655 \circulararc -
180 degrees from
{\xa} {\ya} center at
{\xd} {\yd}
656 \or % Seta de Aplica{\c c}{\~a}o ("|-->")
657 \auxa=
3% valor para o meio-segmento do "rabo" da "seta"
658 %% c{\'a}lculo dos pontos (xmed,ymed) e (xd,yd) para o segmento de recta que
659 %% define o "rabo" da seta
660 \!ucoord
{\number\y}{\number\yl}{\number\xa}{\number\auxa}{\number\d}{\xmed}{-
1}%
661 \!ucoord
{\number\x}{\number\xl}{\number\ya}{\number\auxa}{\number\d}{\ymed}{1}%
662 \!ucoord
{\number\y}{\number\yl}{\number\xa}{\number\auxa}{\number\d}{\xd}{1}%
663 \!ucoord
{\number\x}{\number\xl}{\number\ya}{\number\auxa}{\number\d}{\yd}{-
1}%
664 %% Constru{\c c}{\~a}o da "seta"
665 \arrow <
4pt>
[.2,
1.1] from
{\xa} {\ya} to
{\xb} {\yb}
668 \plot {\xmed} {\ymed} {\xd} {\yd} /
669 \or % Seta de Sobrejec{\c c}{\~a}o ("-->>")
670 \arrow <
4pt>
[.2,
1.1] from
{\xa} {\ya} to
{\xb} {\yb}
671 %% e da segunda "seta"
673 \arrow <
6pt>
[0,
.72] from
{\xa} {\ya} to
{\xb} {\yb}
675 %% Coloca{\c c}{\~a}o do nome do morfismo.
676 %% Se os morfismos s{\~a}o horizontais ou verticais constro{\'\i} uma caixa
677 %% centrada no ponto pr{\'e}viamente calculado. Se as setas s{\~a}o
678 %% obl{\'\i}quas coloca a caixa de forma a n{\~a}o colidir com o morfismo
679 %% tendo em aten{\c c}{\~a}o o quadrante assim como a posi{\c c}{\~a}o
680 %% relativa do morfismo e do respectivo nome.
682 \advance \auxa by -
\x%
684 \put {#7} at
{\xc} {\yc}
687 \advance \auxb by -
\y%
688 \ifnum \auxb=
0 \put {#7} at
{\xc} {\yc}
693 \put {#7} [rb
] at
{\xc} {\yc}
695 \put {#7} [lt
] at
{\xc} {\yc}
699 \put {#7} [lb
] at
{\xc} {\yc}
701 \put {#7} [rt
] at
{\xc} {\yc}
707 \put {#7} [rt
] at
{\xc} {\yc}
709 \put {#7} [lb
] at
{\xc} {\yc}
713 \put {#7} [lt
] at
{\xc} {\yc}
715 \put {#7} [rb
] at
{\xc} {\yc}
724 %% Comando para construir a "seta" curvilinea entre dois objectos
726 %% \cmor(<lista de pontos (n. impar)>){<etiqueta>}
728 %% Em primeiro lugar {\'e} necess{\'a}rio modificar o comando plot de forma a
729 %% que a sintaxe de utiliza{\c c}{\~a}o do novo comando seja coerente com a
730 %% sintaxe dos restantes comandos
732 \def\modifplot(
#1{\!modifqcurve
#1}
733 \def\!modifqcurve(
#1,
#2)
{\x=
#1%
735 \multiply \x by
\expansao%
736 \multiply \y by
\expansao%
739 \def\!modifQjoin(
#1,
#2)(
#3,
#4)
{\x=
#1%
743 \multiply \x by
\expansao%
744 \multiply \y by
\expansao%
745 \multiply \xl by
\expansao%
746 \multiply \yl by
\expansao%
747 \!qjoin (
\x,
\y) (
\xl,
\yl)
% \!qjoin is defined in QUADRATIC
748 \!ifnextchar)
{\!fim
}{\!modifQjoin
}}
749 \def\!fim)
{\ignorespaces}
752 %% O comando para desenhar a seta vai receber a lista de pontos da qual
753 %% retira o {\'u}ltimo par de pontos, dependente da escolha dada pelo
754 %% utilizador a seta vai ser desenhada para cima, para baixo, para a
755 %% direita ou para a esquerda
757 \def\setaxy(
#1{\!pontosxy
#1}
758 \def\!pontosxy(
#1,
#2)
{%
760 \def\!maispontosxy(
#1,
#2)(
#3,
#4)
{%
761 \!ifnextchar)
{\!fimxy
#3,
#4}{\!maispontosxy
}}
762 \def\!fimxy
#1,
#2)
{\x=
#1%
764 \multiply \x by
\expansao
765 \multiply \y by
\expansao
769 \multiply \aux by
\auxa%
772 \multiply \aux by
\auxb%
774 \arrow <
4pt>
[.2,
1.1] from
{\x} {\y} to
{\xl} {\yl}}
778 %% Temos agora a defini{\c c}{\~a}o do comando "cmor"
780 \def\cmor#1 #2(
#3,
#4)
#5{%
781 \!ifnextchar
[{\!cmora
{#1}{#2}{#3}{#4}{#5}}{\!cmora
{#1}{#2}{#3}{#4}{#5}[0] }}
782 \def\!cmora
#1#2#3#4#5[#6]{%
783 \ifcase #2% para cima "\pup" (pointing up)
784 \auxa=
0% x mant{\^e}m-se
786 \or% para baixo "\pdown" (pointing down)
787 \auxa=
0% x mant{\^e}m-se
788 \auxb=-
1% o y "desce"
789 \or% para a direita "\pright" (pointing right)
790 \auxa=
1% o x move-se para a direita
791 \auxb=
0% o y mant{\^e}m-se
792 \or% para a esquerda "\pleft" (pointing left)
793 \auxa=-
1% o x move-se para a esquerda
794 \auxb=
0% o y mant{\^e}m-se
795 \fi % constru{\c c}{\~a}o do arco
796 \ifcase #6 % arco (com seta) s{\'o}lido
797 \modifplot#1% Desenhar o arco
798 % constru{\c c}{\~a}o da seta
800 \or % arco (com seta) a tracejado
802 \modifplot#1% Desenhar o arco
806 \modifplot#1% Desenhar o arco
807 \fi % seta de injec{\c c}{\~a}o
808 %% coloca{\c c}{\~a}o da etiqueta do morfismo
811 \multiply \x by
\expansao%
812 \multiply \y by
\expansao%
813 \put {#5} at
{\x} {\y}}
816 %% Comando para construir os Objectos
817 %% \obj(x,y){<texto>}[<etiqueta>]
820 \!ifnextchar
[{\!obja
{#1}{#2}}{\!obja
{#1}{#2}[Nulo
]}}
821 \def\!obja
#1#2[#3]#4{%
822 \!ifnextchar
[{\!objb
{#1}{#2}{#3}{#4}}{\!objb
{#1}{#2}{#3}{#4}[1]}}
823 \def\!objb
#1#2#3#4[#5]{%
826 \def\!pinta
{\normalsize$
\bullet$
}% para definir o tamanho normal das pintas
829 \!compara
{\!arg
}{\!nulo
}%
830 \ifcompara\def\!arg
{#4}\fi%
831 \multiply \x by
\expansao%
832 \multiply \y by
\expansao%
833 \setbox\caixa=
\hbox{#4}%
834 \!coloca
{(\!arg)(
#1,
#2)(
\number\ht\caixa,
\number\wd\caixa,
\number\dp\caixa)
}{\pilha}%
835 \auxa=
\wd\caixa \divide \auxa by
131072
838 \advance \auxb by
\number\dp\caixa
839 \divide \auxb by
131072
843 % \aux=\ht\caixa \divide \auxa by 131072
844 % \advance \auxa by 5
845 % \auxb=\dp\caixa \divide \auxb by 131072
846 % \advance \auxb by 8
847 \ifcase \tipografo % diagramas comutativos
848 \put{#4} at
{\x} {\y}
849 \or % grafos dirigidos
851 \put{#4} at
{\x} {\y}
853 \put{\!pinta
} at
{\x} {\y}
854 \advance \y by
\number\auxb % height+depth+5
855 \put{#4} at
{\x} {\y}
857 \put{\!pinta
} at
{\x} {\y}
858 \advance \auxa by -
2 % para fazer o ajuste (imperfeito)
859 \advance \auxb by -
2 % ao raio da circunferência de centro (x,y)
860 \advance \x by
\number\auxa % width+5
861 \advance \y by
\number\auxb % height+depth+5
862 \put{#4} at
{\x} {\y}
864 \put{\!pinta
} at
{\x} {\y}
865 \advance \x by
\number\auxa % width+5
866 \put{#4} at
{\x} {\y}
868 \put{\!pinta
} at
{\x} {\y}
869 \advance \auxa by -
2 % para fazer o ajuste (imperfeito)
870 \advance \auxb by -
2 % ao raio da circunferência de centro (x,y)
871 \advance \x by
\number\auxa % width+5
872 \advance \y by -
\number\auxb % height+depth+5
873 \put{#4} at
{\x} {\y}
875 \put{\!pinta
} at
{\x} {\y}
876 \advance \y by -
\number\auxb % height+depth+5
877 \put{#4} at
{\x} {\y}
879 \put{\!pinta
} at
{\x} {\y}
880 \advance \auxa by -
2 % para fazer o ajuste (imperfeito)
881 \advance \auxb by -
2 % ao raio da circunferência de centro (x,y)
882 \advance \x by -
\number\auxa % width+5
883 \advance \y by -
\number\auxb % height+depth+5
884 \put{#4} at
{\x} {\y}
886 \put{\!pinta
} at
{\x} {\y}
887 \advance \x by -
\number\auxa % width+5
888 \put{#4} at
{\x} {\y}
890 \put{\!pinta
} at
{\x} {\y}
891 \advance \auxa by -
2 % para fazer o ajuste (imperfeito)
892 \advance \auxb by -
2 % ao raio da circunferência de centro (x,y)
893 \advance \x by -
\number\auxa % width+5
894 \advance \y by
\number\auxb % height+depth+5
895 \put{#4} at
{\x} {\y}
897 \or % grafos não dirigidos
899 \put{#4} at
{\x} {\y}
901 \put{\!pinta
} at
{\x} {\y}
902 \advance \y by
\number\auxb % height+depth+5
903 \put{#4} at
{\x} {\y}
905 \put{\!pinta
} at
{\x} {\y}
906 \advance \auxa by -
2 % para fazer o ajuste (imperfeito)
907 \advance \auxb by -
2 % ao raio da circunferência de centro (x,y)
908 \advance \x by
\number\auxa % width+5
909 \advance \y by
\number\auxb % height+depth+5
910 \put{#4} at
{\x} {\y}
912 \put{\!pinta
} at
{\x} {\y}
913 \advance \x by
\number\auxa % width+5
914 \put{#4} at
{\x} {\y}
916 \put{\!pinta
} at
{\x} {\y}
917 \advance \auxa by -
2 % ver acima
919 \advance \x by
\number\auxa % width+5
920 \advance \y by -
\number\auxb % height+depth+5
921 \put{#4} at
{\x} {\y}
923 \put{\!pinta
} at
{\x} {\y}
924 \advance \y by -
\number\auxb % height+depth+5
925 \put{#4} at
{\x} {\y}
927 \put{\!pinta
} at
{\x} {\y}
928 \advance \auxa by -
2 % ver acima
930 \advance \x by -
\number\auxa % width+5
931 \advance \y by -
\number\auxb % height+depth+5
932 \put{#4} at
{\x} {\y}
934 \put{\!pinta
} at
{\x} {\y}
935 \advance \x by -
\number\auxa % width+5
936 \put{#4} at
{\x} {\y}
938 \put{\!pinta
} at
{\x} {\y}
939 \advance \auxa by -
2 % ver acima
941 \advance \x by -
\number\auxa % width+5
942 \advance \y by
\number\auxb % height+depth+5
943 \put{#4} at
{\x} {\y}
945 % \or % grafos dirigidos com molduras circulares nos objectos
946 % \advance \auxa by 4
947 % \put{\circle{\auxa}} [Bl] at {\x} {\y}
948 % \put{#4} at {\x} {\y}
949 % \or % grafos não dirigidos com molduras circulares nos objectos
950 \else % grafos com molduras circulares nos objectos
951 \ifnum\auxa<
\auxb % determina a maior das dimensões
956 % se a largura da caixa é menor do que 1em então o tamanho
957 % tamanho é ajustado para esse valor mínimo
960 \aux=
\dimen99 \divide \aux by
131072
963 \advance\aux by -
2 %folga entre o objecto e a moldura
966 \put{\circle{\aux}} [Bl
] at
{\x} {\y}
970 \put{\oval(
\auxa,
\auxb)
} [Bl
] at
{\x} {\y}
972 \put{#4} at
{\x} {\y}
977 \catcode`!=
12 % ***** THIS MUST NEVER BE OMITTED (Ver PiCTeX)