summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/dcpic
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-01-12 23:54:05 +0000
committerKarl Berry <karl@freefriends.org>2006-01-12 23:54:05 +0000
commit8e3144f440d5dc8f7b1ae3bd01db67e10fab5eb2 (patch)
tree22b2f11eda7ee917617962605b673f51eaa175f6 /Master/texmf-dist/tex/latex/dcpic
parent399efd9f62691744f76149b577407c495e4b2ee7 (diff)
dcpic
git-svn-id: svn://tug.org/texlive/trunk@818 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/dcpic')
-rw-r--r--Master/texmf-dist/tex/latex/dcpic/dcpic.sty1200
1 files changed, 1200 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/dcpic/dcpic.sty b/Master/texmf-dist/tex/latex/dcpic/dcpic.sty
new file mode 100644
index 00000000000..b1a65327c08
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/dcpic/dcpic.sty
@@ -0,0 +1,1200 @@
+% $Id: dcpic.sty,v 1.24 2002/11/25 13:51:57 pedro Exp $
+%% DC-PiCTeX
+%% Realizado por Pedro Quaresma de Almeida, Coimbra
+%% 11/1990 (vers{\~a}o 1.0); 10/1991 (vers{\~a}o 1.1);
+%% 9/1993 (vers{\~a}o 1.2); 3/1995 (vers{\~a}o 1.3);
+%% 7/1996 (vers{\~a}o 2.1);
+%% 5/2001 (vers{\~a}o 3.0); 11/2001 (vers{\~a}o 3.1);
+%% 1/2002 (vers{\~a}o 3.2)
+%% 5/2002 (versão 4.0)
+\immediate\write10{Package DCpic 2002/05/16 v4.0}
+
+%% Copyright (c) 1990-2002 Pedro Quaresma <pedro@mat.uc.pt>
+%% The DCpic package is free software; you can redistribute it and/or
+%% modify it under the terms of the GNU General Public License as
+%% published by the Free Software Foundation; either version 2 of the
+%% License, or (at your option) any later version.
+%%
+%% The DCpic package is distributed in the hope that it will be
+%% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+%% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+%% General Public License for more details.
+%%
+%% You should have received a copy of the GNU General Public License
+%% along with this package; if not, write to the Free Software
+%% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+%%
+%%
+%% Coimbra, 16 de Maio de 2002
+%% Pedro Quaresma de Almeida
+%%
+%% DCpic is a package of \TeX\ macros for graph modelling in a
+%% (La)\TeX\ or Con\TeX t document. Its distinguishing features are:
+%% the use of \PiCTeX\ a powerful graphical engine, and a simple
+%% specification syntax. A graph is described in terms of its objects
+%% and its edges. The objects are textual elements and the edges can
+%% have various straight or curved forms.
+%%
+%%
+%% A graph in DCpic is a "picture" in \PiCTeX, in which we place our
+%% {\em objects} and {\em morphisms} (edges). The user's commands in
+%% DCpic are: {\tt begindc} and {\tt enddc} which establishe the
+%% coordinate system where the objects will by placed; {\tt obj}, the
+%% command which defines the place and the contents of each object;
+%% {\tt mor}, and {\tt cmor}, the commands which define the
+%% morphisms, linear and curved edges, and its labels.
+%%
+%% Example:
+%% \begindc{\commdiag}[3]
+%% \obj(10,15){$A$}
+%% \obj(25,15){$B$}
+%% \obj(40,15){$C$}
+%% \mor{$A$}{$B$}{$f$}
+%% \mor{$B$}{$C$}{$g$}
+%% \cmor((10,11)(11,7)(15,6)(25,6)(35,6)(39,7)(40,11))
+%% \pup(25,3){$g\circ f$}
+%% \enddc
+%%
+%% NOTES:
+%% all the numeric values should be integer values.
+%%
+%% Available commands:
+%%
+%% The environment:
+%% \begindc{#1}[#2]
+%% Tipo do grafo
+%% 0 = "commdiag" (diagrama comutativo)
+%% 1 = "digraph" (grafo orientado)
+%% 2 = "undigraph" (grafo não orientado)
+%% (optional) #2 - magnification factor (default value, 30)
+%%
+%% \enddc
+%%
+%% Objects:
+%% \obj(#1,#2)[#3]{#4}[#5]
+%% #1 and #2 - coordenates
+%% (optional) #3 - Label, to be used in the morphims command, if not
+%% present the #4 will be used to that purpose
+%% #4 - Object contents
+%% #5 - placement of the object (default value \north)
+%% 0="\pcent", center
+%% 1="\north", north
+%% 2="\northeast", northeast
+%% 3="\east", east
+%% 4="\southeast", southeast
+%% 5="\south", south
+%% 6="\southwest", southwest
+%% 7="\west", west
+%% 8="\northwest", northwest
+%% !!! Note !!!
+%% if you omit the #3 argument (label) and the #4 argument is a
+%% complex LaTeX command this can cause this command to crash. In
+%% this case you must specify a label (the empty label [], if you do
+%% needed it it for nothing).
+%%
+%% Morphims (linear edges). This commando has to two major variants
+%% i) Starting and Ending objects specification
+%% \mor{#1}{#2}[#5,#6]{#7}[#8,#9]
+%%
+%% As you can see this first form is (intencionaly) badly formed, the
+%% arguments #3 and #4 are missing (the actual command is correctly
+%% formed).
+%%
+%% #1 - The starting object reference
+%% #2 - The ending object reference
+%%
+%% from this two we will obtain the objects coordinates, and also the
+%% dimensions of the enclosing box.
+%%
+%% The objects box dimensions are used to do an automatic adjustment of
+%% the edge width.
+%%
+%% from #1 we obtain (x,y), (#1,#2) in the second form
+%% from #2 we obtain (x',y'), (#3,#4) in the second form
+%%
+%% this values will be passed to the command second form
+%%
+%%ii) Two points coordinates specification
+%% \mor(#1,#2)(#3,#4)[#5,#6]{#7}[#8,#9]
+%%
+%% Now we can describe all the arguments
+%%
+%% #1 and #2 - coordenates (beginning)
+%% #3 and #4 - coordenantes (ending)
+%%(optional)#5,#6 - correction factor (defaul value, 10 and 10)
+%% #5 - actual beginning of the edge
+%% #6 - actual ending of the edge
+%% #7 - text (morphism label)
+%%(optional)#8,#9
+%% #8 - label placement
+%% 1 = \atright, at right, default value
+%% -1 = \atleft, at left
+%% #9 - edge type
+%% 0 = "\solidarrow", default edge
+%% 1 = "\dasharrow"
+%% 2 = "\solidline"
+%% 3 = "\injectionarrow"
+%% 4 = "\aplicationarrow"
+%%
+%% Note: insert a space after the command.
+%%
+%% Curved Morphisms (quadratic edges):
+%% \cmor(#1) #2(#3,#4){#5}[#6]
+%% #1 - list of points (odd number)
+%% #2 - tip direction
+%% 0 = "\pup", pointing up
+%% 1 = "\pdown", pointing down
+%% 2 = "\pright", pointing right
+%% 3 = "\pleft", pointing left
+%% #3 and #4 - coordenates of the label
+%% #5 - morphism label
+%% #6 - edge type
+%% 0 ="\solidarrow", default value
+%% 1 = "\dasharrow"
+%% 2 = "\solidline"
+%%
+%% Notes: insert a space after the command.
+%% the space after the list of points is mandatory
+%%
+%% Exemples:
+%%\documentclass[a4paper,11pt]{article}
+%%\usepackage{dcpic,pictexwd}
+%%
+%%\begin{document}
+%%\begindc[3]
+%%\obj(14,11){$A$}
+%%\obj(39,11){$B$}
+%%\mor(14,12)(39,12){$f$}%[\atright,\solidarrow]
+%%\mor(39,10)(14,10){$g$}%[\atright,\solidarrow]
+%%\cmor((10,10)(6,11)(5,15)(6,19)(10,20)(14,19)(15,15))
+%% \pdown(2,20){$id_A$}
+%%\cmor((40,7)(41,3)(45,2)(49,3)(50,7)(49,11)(45,12))
+%% \pleft(54,3){$id_B$}
+%%\enddc
+%%
+%%\begindc{\commdiag}[3]
+%%\obj(10,15)[A]{$A$}
+%%\obj(40,15)[Aa]{$A$}
+%%\obj(25,15)[B]{$B$}
+%%\mor{A}{B}{$f$}%[\atright,\solidarrow]
+%%\mor{B}{Aa}{$g$}%[\atright,\solidarrow]
+%%\cmor((10,11)(11,7)(15,6)(25,6)(35,6)(39,7)(40,11))
+%% \pup(25,3){$id_A$}
+%%\enddc
+%%
+%%\newcommand{\barraA}{\vrule height2em width0em depth0em}
+%%\newcommand{\barraB}{\vrule height1.6em width0em depth0em}
+%%\begindc{\commdiag}[35]
+%%\obj(1,1)[Gr]{$G$}
+%%\obj(3,1)[Grstar]{$G_{r^*}$}
+%%\obj(5,1)[H]{$H$}
+%%\obj(2,2)[SigmaG]{$\Sigma^G$}
+%%\obj(6,2)[SigmaH]{$\Sigma^H$}
+%%\obj(1,3)[Lm]{$L_m$}
+%%\obj(3,3)[Krm]{$K_{r,m}$}
+%%\obj(5,3)[Rmstar]{$R_{m^*}$}
+%%\obj(1,5)[L]{$L$}
+%%\obj(3,5)[Lr]{$L_r$}
+%%\obj(5,5)[R]{$R$}
+%%\obj(2,6)[SigmaL]{$\Sigma^L$}
+%%\obj(6,6)[SigmaR]{$\Sigma^R$}
+%%\mor{Gr}{SigmaG}{$\lambda^G$}
+%%\mor{Grstar}{Gr}{$i_5$}[\atleft,\aplicationarrow]
+%%\mor{Grstar}{H}{$r^*$}[\atright,\solidarrow]
+%%\mor{H}{SigmaH}{$\lambda^H$}[\atright,\dasharrow]
+%%\mor{SigmaG}{SigmaH}{$\varphi^{r^*}$}[\atright,\solidarrow]
+%%\mor{Lm}{Gr}{$m$}[\atright,\solidarrow]
+%%\mor{Lm}{L}{$i_2$}[\atleft,\aplicationarrow]
+%%\mor{Krm}{Lm}{$i_3\quad$}[\atright,\aplicationarrow]
+%%\mor{Krm}{Rmstar}{$r$}
+%%\mor{Krm}{Lr}{$i_4$}[\atright,\aplicationarrow]
+%%\mor{Krm}{Grstar}{$m$}
+%%\mor{Rmstar}{R}{$i_6$}[\atright,\aplicationarrow]
+%%\mor{Rmstar}{H}{$m^*$}
+%%\mor{L}{SigmaL}{$\lambda^L$}
+%%\mor{Lr}{L}{$i_1\quad$}[\atright,\aplicationarrow]
+%%\mor{Lr}{R}{$r$}
+%%\mor{R}{SigmaR}{$\lambda^R$}[\atright,\solidarrow]
+%%\mor{SigmaL}{SigmaG}{$\varphi^m$}[\atright,\solidarrow]
+%%\mor{SigmaL}{SigmaR}{$\varphi^r$}
+%%\mor{SigmaR}{SigmaH}{$\varphi^{m^*}$}
+%%\enddc
+%%
+%%\end{document}
+%%-----------------//-------------
+%% Modifica{\c c}{\~o}es (9/1993)
+%% argumento "dist{\^a}ncia entre as extremidades da seta e os
+%% objectos" passou a ser opcional; uma nova op{\c c}{\~a}o para as
+%% "setas" (op{\c c}{\~a}o 3).
+%%
+%% 2/3/1995 (vers{\~a}o 1.3)
+%% foi acrescentado o tipo de seta de aplica{\c c}{\~a}o
+%% (op{\c c}{\~a}o 4) a dist{\^a}ncia da etiqueta {\`a} seta respectiva
+%% passou a ser fixa (10 unidades de medida).
+%% 15/7/1996 (versão 2.1)
+%% O comando "\mor" passou a ter uma sintaxe distinta. Os
+%% par{\^a}metros 5 e 6 passaram a ser a dist{\^a}ncia entre os
+%% objectos e os extremos da seta o par{\^a}metro 7 {\'e} o nome do
+%% morfismo e os par{\^a}metros 8 e 9, coloca{\c c}{\~a}o do morfismo
+%% e tipo de morfismo passaram a ser opcionais.
+%%
+%% 5/2001 (vers{\~a}o 3.0)
+%% Implementa{\c c}{\~a}o do comando "\cmor" baseado no comando
+%% de desenho de curvas quadr{\'a}ticas pelo PiCTeX
+%%
+%% 11/2001 (vers{\~a}o 3.1)
+%% Modifica{\c c}{\~a}o das pontas das setas de forma a estas ficarem
+%% semelhantes {\`a}s setas (s{\'\i}mbolos) dos TeX.
+%%
+%% 1/2002 (vers{\~a}o 3.2)
+%% Modifica{\c c}{\~a}o dos comandos "obj" e "mor" de forma a introduzir
+%% a especifica{\c c}{\~a}o l{\'o}gica dos morfismos, isto {\'e}, passa-se a
+%% dizer qual {\'e} o objecto de partida e/ou o objecto de chegada
+%% em vez de ter de especificar o morfismo em termos de
+%% coordenadas.
+%% Por outro lado o tamanho das setas passa a ser ajustado
+%% automaticamente em rela{\c c}{\~a}o ao tamanho dos objectos.
+%%
+%% 5/2002 (versão 4.0)
+%% Modificação dos comandos "begindc" e "obj"
+%% !!! Modificação da sintaxe destes comandos !!!
+%% O comando "begindc" passou a ter um argumento (obrigatório)
+%% que nos permite especificar o tipo de grafo que estamos a
+%% querer especificar:
+%% "commdiag" (0), para diagramas comutativos
+%% "digraph" (1), para grafos orientados
+%% "undigraph" (1), para grafos não orientados
+%% O comando "obj" modificou a sua sintaxe passou a ter um (após
+%% a especificação das coordenadas, um argumento opcional, um
+%% argumento obrigatório, e um argumento opcional. O primeiro
+%% argumento opcional dá-nos a etiqueta que serve como
+%% referência para a especificação dos morfismos, na sua
+%% ausência usa-se o argumento obrigatório para esse efeito, o
+%% argumento obrigatório dá-nos o "conteúdo" do objecto, nos
+%% diagramas comutativos é centrado no ponto dado pelas
+%% coordenadas sendo o argumento seguinte simplesmente ignorado,
+%% nos grafos o "conteúdo" é colocado numa posição a norte, a
+%% noroeste, a este, ..., sendo que a posição concreta é
+%% especificada pelo último dos argumentos deste comando, o
+%% valor por omissão é o "norte".
+%%
+%%-----------------//-------------
+
+\catcode`!=11 % ***** THIS MUST NEVER BE OMITTED (Ver PiCTeX)
+
+\newcount\aux%
+\newcount\auxa%
+\newcount\auxb%
+\newcount\m%
+\newcount\n%
+\newcount\x%
+\newcount\y%
+\newcount\xl%
+\newcount\yl%
+\newcount\d%
+\newcount\dnm%
+\newcount\xa%
+\newcount\xb%
+\newcount\xmed%
+\newcount\xc%
+\newcount\xd%
+\newcount\ya%
+\newcount\yb%
+\newcount\ymed%
+\newcount\yc%
+\newcount\yd
+%% "variáveis globais"
+\newcount\expansao%
+\newcount\tipografo% versão 4.0
+\newcount\distanciaobjmor% versão 4.0
+\newcount\tipoarco% versão 4.0
+%\newif\ifarredondada% versão 4.0 (valor inicial "false")
+\newif\ifpara%
+%% version 3.2
+\newbox\caixa%
+\newbox\caixaaux%
+\newif\ifnvazia%
+\newif\ifvazia%
+\newif\ifcompara%
+\newif\ifdiferentes%
+\newcount\xaux%
+\newcount\yaux%
+\newcount\guardaauxa%
+\newcount\alt%
+\newcount\larg%
+\newcount\prof%
+%% para os ajustes
+\newcount\auxqx
+\newcount\auxqy
+\newif\ifajusta%
+\newif\ifajustadist
+\def\objPartida{}%
+\def\objChegada{}%
+\def\objNulo{}%
+
+
+%%
+%% Stack specification
+%%
+
+%%
+%% Emtpy stack
+%%
+\def\!vazia{:}
+
+%%
+%% Is Empty? : Stack -> Bool
+%%
+%% nvazia - True if Not Empy
+%% vazia - True if Empty
+\def\!pilhanvazia#1{\let\arg=#1%
+\if:\arg\ \nvaziafalse\vaziatrue \else \nvaziatrue\vaziafalse\fi}
+
+%%
+%% Push : Elems x Stack -> Stack
+%%
+\def\!coloca#1#2{\edef\pilha{#1.#2}}
+
+%%
+%% Top : Stack -> Elems
+%%
+%% the empty stack is not taken care
+%% the element is "kept" ("guardado")
+\def\!guarda(#1)(#2,#3)(#4,#5,#6){\def\id{#1}%
+\xaux=#2%
+\yaux=#3%
+\alt=#4%
+\larg=#5%
+\prof=#6%
+}
+
+\def\!topaux#1.#2:{\!guarda#1}
+\def\!topo#1{\expandafter\!topaux#1}
+
+%%
+%% Pop : Stack -> Stack
+%%
+%% the empty stack is not taken care
+\def\!popaux#1.#2:{\def\pilha{#2:}}
+\def\!retira#1{\expandafter\!popaux#1}
+
+%%
+%% Compares words : Word x Word -> Bool
+%%
+%% compara - True if equal
+%% diferentes - True if not equal
+\def\!comparaaux#1#2{\let\argA=#1\let\argB=#2%
+\ifx\argA\argB\comparatrue\diferentesfalse\else\comparafalse\diferentestrue\fi}
+
+\def\!compara#1#2{\!comparaaux{#1}{#2}}
+
+%%Comando Interno
+%% Valor absoluto (absolute value)
+%% \absoluto{n}{absn}
+%% entrada
+%% n - natural
+%% sa{\'\i}da
+%% absn - o valor absoluto de n
+\def\!absoluto#1#2{\n=#1%
+ \ifnum \n > 0
+ #2=\n
+ \else
+ \multiply \n by -1
+ #2=\n
+ \fi}
+
+
+%% Name definitions for edge types and directions
+\def\solidarrow{0}
+\def\dasharrow{1}
+\def\solidline{2}
+\def\injectionarrow{3}
+\def\aplicationarrow{4}
+%% Name definitions for edge label placement
+\def\atright{-1}
+\def\atleft{1}
+%% Tip direction for curved edges
+\def\pup{0}
+\def\pdown{1}
+\def\pright{2}
+\def\pleft{3}
+%% Type of graph
+\def\commdiag{0}
+\def\digraph{1}
+\def\undigraph{2}
+\def\cdigraph{3}
+\def\cundigraph{4}
+%% Posicionamento da etiquetas nos grafos
+\def\pcent{0}
+\def\north{1}
+\def\northeast{2}
+\def\east{3}
+\def\southeast{4}
+\def\south{5}
+\def\southwest{6}
+\def\west{7}
+\def\northwest{8}
+
+
+
+%%Comando Interno
+%% Ajusta a dist{\^a}ncia entre as setas e os objectos em fun{\c c}{\~a}o das
+%% dimens{\~o}es destes {\'u}ltimos
+%% \ajusta{x}{xl}{y}{yl}{d}{Objecto}
+%% entrada
+%% (x,y) e (xl,yl), coordenadas dos pontos de {\'\i}nicio e fim da seta
+%% d, dist{\^a}ncia especificada pelo utilizador ou 10 (valor por
+%% omiss{\~a}o), Objecto d{\'a}-nos a refer{\^e}ncia do objecto ao qual se est{\'a} a
+%% efectuar o ajuste.
+%% sa{\'\i}da
+%% d, dist{\^a}ncia alterada.
+%%
+%% A dist{\^a}ncia alterada {\'e} o maior valor entre 10 e as dimens{\~o}es
+%% apropriadas da caixa que cont{\^e}m o objecto.
+%% Se o utilizador especificar um valor essa especifica{\c c}{\~a}o
+%% n{\~a}o {\'e} alterada.
+%%
+%% Se a seta {\'e} horizontal usa-se o valor da largura
+%% Se a seta {\'e} vertical usa-se:
+%% o valor da altura se a seta est{\'a} no 1o ou 2o quadrante
+%% o valor da profundidade se a seta est{\'a} no 3o ou 4o quadrante
+%% Se a seta {\'e} {\'o}bliqua vai-se escolher o valor conforme:
+%% de 315 a 45 graus usa-se a largura
+%% de 45 a 135 graus usa-se a altura
+%% de 135 a 225 graus usa-se a largura
+%% de 225 a 315 graus usa-se a profundidade
+\def\!ajusta#1#2#3#4#5#6{\aux=#5%
+ \let\auxobj=#6%
+ \ifcase \tipografo % diagramas comutativos
+ \ifnum\number\aux=10
+ \ajustadisttrue % se o valor é o valor por omissão ajusta
+ \else
+ \ajustadistfalse % caso contrário não ajusta
+ \fi
+ \else % grafos (dirigidos, não dirigidos, com molduras)
+ \ajustadistfalse
+% \or % grafos não dirigidos
+% \ajustadistfalse
+% \else % grafos dirigidos com molduras circulares nos objectos
+% \ifnum\number\aux=8
+% \ajustadisttrue % se o valor é o valor por omissão ajusta
+% \else
+% \ajustadistfalse % caso contrário não ajusta
+% \fi
+ \fi
+ \ifajustadist
+% \tiny Vou ajustar %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \ifnum\number\aux=10% verificar se s{\~a}o os valores por omiss{\~a}o
+ \let\pilhaaux=\pilha%
+ \loop%
+ \!topo{\pilha}%
+ \!retira{\pilha}%
+ \!compara{\id}{\auxobj}%
+ \ifcompara\nvaziafalse \else\!pilhanvazia\pilha \fi%
+ \ifnvazia%
+ \repeat%
+%% rep{\~o}e os valores na pilha
+ \let\pilha=\pilhaaux%
+ \ifvazia%
+ \ifdiferentes%
+%%
+%% N{\~a}o {\'e} poss{\'\i}vel efectuar o ajuste dado o utilizador n{\~a}o ter
+%% especificado uma etiqueta para o objecto em quest{\~a}o. {\'E} dado o
+%% valor de 10, igual ao valor por omiss{\~a}o.
+%%
+ \larg=1310720% n{\~a}o faz o ajuste
+ \prof=655360%
+ \alt=655360%
+ \fi%
+ \fi%
+ \divide\larg by 131072
+ \divide\prof by 65536
+ \divide\alt by 65536
+ \ifnum\number\y=\number\yl
+%% Caso 1 -- seta horizontal
+%%
+%% divide-se por 131072 para se obter metade da largura da caixa em
+%% pontos (pt), isto dado que o texto est{\'a} centrado na caixa. Soma-se
+%% mais tr{\^e}s, que constitue um ajuste imp{\'\i}rico.
+ \advance\larg by 3
+ \ifnum\number\larg>\aux
+ #5=\larg
+ \fi
+ \else
+ \ifnum\number\x=\number\xl
+ \ifnum\number\yl>\number\y
+%% Caso 2.1 -- seta vertical de cima para baixa
+%%
+ \ifnum\number\alt>\aux
+ #5=\alt
+ \fi
+ \else
+%% Caso 2.2 -- seta vertical de baixo para cima
+%%
+%% divide-se por 65536 para se obter a altura da caixa em pt. O ajuste
+%% de 5 foi obtido imp{\'\i}ricamente
+ \advance\prof by 5
+ \ifnum\number\prof>\aux
+ #5=\prof
+ \fi
+ \fi
+ \else
+%% Caso 3 -- seta obl{\'\i}qua
+%% Caso 3.1 de 315o a 45o; |x-xl|>|y-yl| e
+%% Caso 3.3 de 135o a 225o; |x-xl|>|y-yl|; Largura
+ \auxqx=\x
+ \advance\auxqx by -\xl
+ \!absoluto{\auxqx}{\auxqx}%
+ \auxqy=\y
+ \advance\auxqy by -\yl
+ \!absoluto{\auxqy}{\auxqy}%
+ \ifnum\auxqx>\auxqy
+ \ifnum\larg<10
+ \larg=10
+ \fi
+ \advance\larg by 3
+ #5=\larg
+ \else
+%% Caso 3.2 de 45o a 135o; |x-xl|<|y-yl| e y>0; Largura
+ \ifnum\yl>\y
+ \ifnum\larg<10
+ \larg=10
+ \fi
+ \advance\alt by 6
+ #5=\alt
+ \else
+%% Caso 3.4 de 225o a 315o; |x-xl|<|y-yl| e y<0; Profundidade
+ \advance\prof by 11
+ #5=\prof
+ \fi
+ \fi
+ \fi
+ \fi
+\fi} % o ramo "else" {\'e} omisso
+
+
+%%Comando Interno
+%% C{\'a}lculo da Raiz Quadrada
+%% raiz{n}{m}
+%% entrada
+%% n - natural
+%% sa{\'\i}da
+%% n - natural
+%% m - maior natural contido na raiz quadrada de n
+\def\!raiz#1#2{\n=#1%
+ \m=1%
+ \loop
+ \aux=\m%
+ \advance \aux by 1%
+ \multiply \aux by \aux%
+ \ifnum \aux < \n%
+ \advance \m by 1%
+ \paratrue%
+ \else\ifnum \aux=\n%
+ \advance \m by 1%
+ \paratrue%
+ \else\parafalse%
+ \fi
+ \fi
+ \ifpara%
+ \repeat
+#2=\m}
+
+%%Comando Interno
+%% Calcula os pontos de
+%% come{\c c}o da "seta"
+%% fim da "seta"
+%% coloca{\c c}{\~a}o do s{\'\i}mbolo
+%%
+%% ucoord{x1}{x2}{x3}{x4}{x5}{x6}{+|- 1}
+%% entrada
+%% x1,x2,x3,x4,x5
+%% sa{\'\i}da
+%% x6
+%%
+%% x2 - x1
+%% x6 = x3 +|- ------- x4
+%% x5
+\def\!ucoord#1#2#3#4#5#6#7{\aux=#2%
+ \advance \aux by -#1%
+ \multiply \aux by #4%
+ \divide \aux by #5%
+ \ifnum #7 = -1 \multiply \aux by -1 \fi%
+ \advance \aux by #3%
+#6=\aux}
+
+%%Comando Interno
+%% C{\'a}lculo do Quadrado da Dist{\^a}ncia Euclidiana entre dois pontos
+%% quadrado{n}{m}{l}
+%% entrada
+%% n - natural
+%% m - natural
+%% sa{\'\i}da
+%% l = (n-m)*(n-m)
+\def\!quadrado#1#2#3{\aux=#1%
+ \advance \aux by -#2%
+ \multiply \aux by \aux%
+#3=\aux}
+
+%%Comando Interno
+%% C{\'a}lculo auxiliar para determinar a dist{\^a}ncia entre o nome do
+%% morfismo e a seta.
+%% entrada
+%% (x,y), (x',y') e o nome do morfismo
+%% sa{\'\i}da
+%% dnm - dist{\^a}ncia do nome ao morfismo respectivo devidamente
+%% compensada pelo tamanho do objecto
+%% Observa{\c c}{\~o}es
+%% A compensa{\c c}{\~a}o s{\'o} est{\'a} a ser feita para setas
+%% horizontais e verticais. As obl{\'\i}quas s{\~a}o tratadas de
+%% outra forma.
+%% algoritmo
+%% caixa0 <- nome do morfismo
+%% se x-xl = 0 entao {recta vertical}
+%% aux <- largura da caixa0
+%% dnm <- convers{\~a}o-sp-pt(aux)/2+3
+%% sen{\~a}o {recta n{\~a}o vertical}
+%% se y-yl = 0 entao {recta horizontal}
+%% aux <- altura+profundidade da caixa0
+%% dnm <- convers{\~a}o-sp-pt(aux)/2+3
+%% sen{\~a}o {recta obl{\'\i}qua}
+%% dnm <- 3
+%% fimse
+%% fimse
+%% fimalgoritmo
+\def\!distnomemor#1#2#3#4#5#6{\setbox0=\hbox{#5}%
+ \aux=#1
+ \advance \aux by -#3
+ \ifnum \aux=0
+ \aux=\wd0 \divide \aux by 131072
+ \advance \aux by 3
+ #6=\aux
+ \else
+ \aux=#2
+ \advance \aux by -#4
+ \ifnum \aux=0
+ \aux=\ht0 \advance \aux by \dp0 \divide \aux by 131072
+ \advance \aux by 3
+ #6=\aux%
+ \else
+ #6=3
+ \fi
+ \fi
+}
+
+
+%%
+%% O ambiente "begindc...enddc"
+%%
+\def\begindc#1{\!ifnextchar[{\!begindc{#1}}{\!begindc{#1}[30]}}
+\def\!begindc#1[#2]{\beginpicture
+ \let\pilha=\!vazia
+ \setcoordinatesystem units <1pt,1pt>
+ \expansao=#2
+ \ifcase #1
+ \distanciaobjmor=10
+ \tipoarco=0 % seta
+ \tipografo=0 % diagrama comutativo
+ \or
+ \distanciaobjmor=2
+ \tipoarco=0 % seta
+ \tipografo=1 % grafo orientado
+ \or
+ \distanciaobjmor=1
+ \tipoarco=2 % linha
+ \tipografo=2 % grafo não orientado
+ \or
+ \distanciaobjmor=8
+ \tipoarco=0 % seta
+ \tipografo=3 % grafo orientado
+% \arredondadotrue % objectos com molduras circulares
+ \or
+ \distanciaobjmor=8
+ \tipoarco=2 % linha
+ \tipografo=4 % grafo não orientado
+% \arredondadotrue % objectos com molduras circulares
+ \fi}
+
+\def\enddc{\endpicture}
+
+
+%%
+%% Comando para construir a "seta" entre dois objectos
+%%
+%% Os pontos definidores da seta e da etiqueta respectiva s{\~a}o:
+%%
+%% (xd,yd)
+%% o
+%% |
+%% o------o---------o---------o------o
+%%(x,y) (xa,ya) (xm,ym) (xb,yb)(xl,yl)
+%%
+\def\mor{%
+ \!ifnextchar({\!morxy}{\!morObjA}}
+\def\!morxy(#1,#2){%
+ \!ifnextchar({\!morxyl{#1}{#2}}{\!morObjB{#1}{#2}}}
+\def\!morxyl#1#2(#3,#4){%
+ \!ifnextchar[{\!mora{#1}{#2}{#3}{#4}}{\!mora{#1}{#2}{#3}{#4}[\number\distanciaobjmor,\number\distanciaobjmor]}}%
+\def\!morObjA#1{%
+ \let\pilhaaux=\pilha%
+ \def\objPartida{#1}%
+ \loop%
+ \!topo\pilha%
+ \!retira\pilha%
+ \!compara{\id}{\objPartida}%
+ \ifcompara \nvaziafalse \else \!pilhanvazia\pilha \fi%
+ \ifnvazia%
+ \repeat%
+ \ifvazia%
+ \ifdiferentes%
+%%
+%% Mensagem de erro e atribui{\c c}{\~a}o de valores fict{\'\i}cios aos
+%% argumentos dos comandos que se seguem.
+%%
+ Error: Incorrect label specification%
+ \xaux=1%
+ \yaux=1%
+ \fi%
+ \fi%
+ \let\pilha=\pilhaaux%
+ \!ifnextchar({\!morxyl{\number\xaux}{\number\yaux}}{\!morObjB{\number\xaux}{\number\yaux}}}
+\def\!morObjB#1#2#3{%
+ \x=#1
+ \y=#2
+ \def\objChegada{#3}%
+ \let\pilhaaux=\pilha%
+ \loop
+ \!topo\pilha %
+ \!retira\pilha%
+ \!compara{\id}{\objChegada}%
+ \ifcompara \nvaziafalse \else \!pilhanvazia\pilha \fi
+ \ifnvazia
+ \repeat
+ \ifvazia
+ \ifdiferentes%
+%%
+%% Mensagem de erro e atribui{\c c}{\~a}o de valores fict{\'\i}cios aos
+%% argumentos dos comandos que se seguem.
+%%
+ Error: Incorrect label specification
+ \xaux=\x%
+ \advance\xaux by \x%
+ \yaux=\y%
+ \advance\yaux by \y%
+ \fi
+ \fi
+ \let\pilha=\pilhaaux
+ \!ifnextchar[{\!mora{\number\x}{\number\y}{\number\xaux}{\number\yaux}}{\!mora{\number\x}{\number\y}{\number\xaux}{\number\yaux}[\number\distanciaobjmor,\number\distanciaobjmor]}}
+\def\!mora#1#2#3#4[#5,#6]#7{%
+ \!ifnextchar[{\!morb{#1}{#2}{#3}{#4}{#5}{#6}{#7}}{\!morb{#1}{#2}{#3}{#4}{#5}{#6}{#7}[1,\number\tipoarco] }}
+\def\!morb#1#2#3#4#5#6#7[#8,#9]{\x=#1%
+ \y=#2%
+ \xl=#3%
+ \yl=#4%
+ \multiply \x by \expansao%
+ \multiply \y by \expansao%
+ \multiply \xl by \expansao%
+ \multiply \yl by \expansao%
+%%
+%% calcular a dist{\^a}ncia Euclidiana entre dois pontos
+%% d = \sqrt((x-xl)^2+(y-yl)^2)
+%%
+ \!quadrado{\number\x}{\number\xl}{\auxa}%
+ \!quadrado{\number\y}{\number\yl}{\auxb}%
+ \d=\auxa%
+ \advance \d by \auxb%
+ \!raiz{\d}{\d}%
+%%
+%% o ponto (xa,ya) est{\'a} {\`a} dist{\^a}ncia #5 (valor por omiss{\~a}o 10) do ponto
+%% (x,y)
+%%
+%% como existem dois pontos em considera{\c c}{\~a}o, o ponto de partida e o
+%% ponto de chegada, vai sei necess{\'a}rio recuperar de novo os seus
+%% valores por pesquisa na pilha
+ \auxa=#5
+ \!compara{\objNulo}{\objPartida}%
+ \ifdiferentes% S{\'o} vai fazer o ajuste quando {\'e} necess{\'a}rio
+ \!ajusta{\x}{\xl}{\y}{\yl}{\auxa}{\objPartida}%
+ \ajustatrue
+ \def\objPartida{}% re-inicializar o valor do Objecto de Partida
+ \fi
+%% vai guardar o valor de auxa (ap{\'o}s ajuste) para ser usado no caso
+%% dos morfismos de injec{\c c}{\~a}o.
+ \guardaauxa=\auxa
+%%
+ \!ucoord{\number\x}{\number\xl}{\number\x}{\auxa}{\number\d}{\xa}{1}%
+ \!ucoord{\number\y}{\number\yl}{\number\y}{\auxa}{\number\d}{\ya}{1}%
+%% auxa vai ter o valor da dist{\^a}ncia entre os objectos menos a
+%% dist{\^a}ncia da seta ao objecto (10 por omiss{\~a}o)
+ \auxa=\d%
+%%
+%% o ponto (xb,yb) est{\'a} {\`a} dist{\^a}ncia #6 (valor por omiss{\~a}o 10) do ponto
+%% (xl,yl)
+%%
+ \auxb=#6
+ \!compara{\objNulo}{\objChegada}%
+ \ifdiferentes% S{\'o} vai fazer o ajuste quando {\'e} necess{\'a}rio
+% Vou ajustar
+ \!ajusta{\x}{\xl}{\y}{\yl}{\auxb}{\objChegada}%
+ \def\objChegada{}% re-inicializar o valor do Objecto de Chegada
+ \fi
+ \advance \auxa by -\auxb%
+ \!ucoord{\number\x}{\number\xl}{\number\x}{\number\auxa}{\number\d}{\xb}{1}%
+ \!ucoord{\number\y}{\number\yl}{\number\y}{\number\auxa}{\number\d}{\yb}{1}%
+ \xmed=\xa%
+ \advance \xmed by \xb%
+ \divide \xmed by 2
+ \ymed=\ya%
+ \advance \ymed by \yb%
+ \divide \ymed by 2
+%%
+%%
+ \!distnomemor{\number\x}{\number\y}{\number\xl}{\number\yl}{#7}{\dnm}%
+ \!ucoord{\number\y}{\number\yl}{\number\xmed}{\number\dnm}{\number\d}{\xc}{-#8}%
+ \!ucoord{\number\x}{\number\xl}{\number\ymed}{\number\dnm}{\number\d}{\yc}{#8}%
+\ifcase #9 % seta s{\'o}lida
+ \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
+\or % seta a tracejado
+ \setdashes
+ \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
+ \setsolid
+\or % linha s{\'o}lida
+ \setlinear
+ \plot {\xa} {\ya} {\xb} {\yb} /
+\or % seta de injec{\c c}{\~a}o
+%% C{\'a}lculos auxiliares
+%%
+%% 3 valor para o raio do "rabo" da "seta"
+%%
+%% repor o valor de auxa
+ \auxa=\guardaauxa
+%% dar a compensa{\c c}{\~a}o para o "rabo"
+ \advance \auxa by 3%
+%%
+%% IMPORTANTE os valores de xa e ya v{\~a}o ser alterados
+%%
+ \!ucoord{\number\x}{\number\xl}{\number\x}{\number\auxa}{\number\d}{\xa}{1}%
+ \!ucoord{\number\y}{\number\yl}{\number\y}{\number\auxa}{\number\d}{\ya}{1}%
+ \!ucoord{\number\y}{\number\yl}{\number\xa}{3}{\number\d}{\xd}{-1}%
+ \!ucoord{\number\x}{\number\xl}{\number\ya}{3}{\number\d}{\yd}{1}%
+%% Constru{\c c}{\~a}o da "seta"
+ \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
+%% e do seu "rabo"
+ \circulararc -180 degrees from {\xa} {\ya} center at {\xd} {\yd}
+\or % seta de aplica{\c c}{\~a}o ("|-->")
+ \auxa=3% valor para o meio-segmento do "rabo" da "seta"
+%% c{\'a}lculo dos pontos (xmed,ymed) e (xd,yd) para o segmento de recta que
+%% define o "rabo" da seta
+ \!ucoord{\number\y}{\number\yl}{\number\xa}{\number\auxa}{\number\d}{\xmed}{-1}%
+ \!ucoord{\number\x}{\number\xl}{\number\ya}{\number\auxa}{\number\d}{\ymed}{1}%
+ \!ucoord{\number\y}{\number\yl}{\number\xa}{\number\auxa}{\number\d}{\xd}{1}%
+ \!ucoord{\number\x}{\number\xl}{\number\ya}{\number\auxa}{\number\d}{\yd}{-1}%
+%% Constru{\c c}{\~a}o da "seta"
+ \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
+%% e do seu "rabo"
+ \setlinear
+ \plot {\xmed} {\ymed} {\xd} {\yd} /
+\fi
+%% Coloca{\c c}{\~a}o do nome do morfismo.
+%% Se os morfismos s{\~a}o horizontais ou verticais constro{\'\i} uma caixa
+%% centrada no ponto pr{\'e}viamente calculado. Se as setas s{\~a}o
+%% obl{\'\i}quas coloca a caixa de forma a n{\~a}o colidir com o morfismo
+%% tendo em aten{\c c}{\~a}o o quadrante assim como a posi{\c c}{\~a}o
+%% relativa do morfismo e do respectivo nome.
+\auxa=\xl
+\advance \auxa by -\x%
+\ifnum \auxa=0
+ \put {#7} at {\xc} {\yc}
+\else
+ \auxb=\yl
+ \advance \auxb by -\y%
+ \ifnum \auxb=0 \put {#7} at {\xc} {\yc}
+ \else
+ \ifnum \auxa > 0
+ \ifnum \auxb > 0
+ \ifnum #8=1
+ \put {#7} [rb] at {\xc} {\yc}
+ \else
+ \put {#7} [lt] at {\xc} {\yc}
+ \fi
+ \else
+ \ifnum #8=1
+ \put {#7} [lb] at {\xc} {\yc}
+ \else
+ \put {#7} [rt] at {\xc} {\yc}
+ \fi
+ \fi
+ \else
+ \ifnum \auxb > 0
+ \ifnum #8=1
+ \put {#7} [rt] at {\xc} {\yc}
+ \else
+ \put {#7} [lb] at {\xc} {\yc}
+ \fi
+ \else
+ \ifnum #8=1
+ \put {#7} [lt] at {\xc} {\yc}
+ \else
+ \put {#7} [rb] at {\xc} {\yc}
+ \fi
+ \fi
+ \fi
+ \fi
+\fi
+}
+
+%%
+%% Comando para construir a "seta" curvilinea entre dois objectos
+%%
+%% \cmor(<lista de pontos (n. impar)>){<etiqueta>}
+%%
+%% Em primeiro lugar {\'e} necess{\'a}rio modificar o comando plot de forma a
+%% que a sintaxe de utiliza{\c c}{\~a}o do novo comando seja coerente com a
+%% sintaxe dos restantes comandos
+%%
+\def\modifplot(#1{\!modifqcurve #1}
+\def\!modifqcurve(#1,#2){\x=#1%
+ \y=#2%
+ \multiply \x by \expansao%
+ \multiply \y by \expansao%
+ \!start (\x,\y)
+ \!modifQjoin}
+\def\!modifQjoin(#1,#2)(#3,#4){\x=#1%
+ \y=#2%
+ \xl=#3%
+ \yl=#4%
+ \multiply \x by \expansao%
+ \multiply \y by \expansao%
+ \multiply \xl by \expansao%
+ \multiply \yl by \expansao%
+ \!qjoin (\x,\y) (\xl,\yl) % \!qjoin is defined in QUADRATIC
+ \!ifnextchar){\!fim}{\!modifQjoin}}
+\def\!fim){\ignorespaces}
+
+%%
+%% O comando para desenhar a seta vai receber a lista de pontos da qual
+%% retira o {\'u}ltimo par de pontos, dependente da escolha dada pelo
+%% utilizador a seta vai ser desenhada para cima, para baixo, para a
+%% direita ou para a esquerda
+%%
+\def\setaxy(#1{\!pontosxy #1}
+\def\!pontosxy(#1,#2){%
+ \!maispontosxy}
+\def\!maispontosxy(#1,#2)(#3,#4){%
+ \!ifnextchar){\!fimxy#3,#4}{\!maispontosxy}}
+\def\!fimxy#1,#2){\x=#1%
+ \y=#2
+ \multiply \x by \expansao
+ \multiply \y by \expansao
+ \xl=\x%
+ \yl=\y%
+ \aux=1%
+ \multiply \aux by \auxa%
+ \advance\xl by \aux%
+ \aux=1%
+ \multiply \aux by \auxb%
+ \advance\yl by \aux%
+ \arrow <4pt> [.2,1.1] from {\x} {\y} to {\xl} {\yl}}
+
+
+%%
+%% Temos agora a defini{\c c}{\~a}o do comando "cmor"
+%%
+\def\cmor#1 #2(#3,#4)#5{%
+ \!ifnextchar[{\!cmora{#1}{#2}{#3}{#4}{#5}}{\!cmora{#1}{#2}{#3}{#4}{#5}[0] }}
+\def\!cmora#1#2#3#4#5[#6]{%
+ \ifcase #2% para cima "\pup" (pointing up)
+ \auxa=0% x mant{\^e}m-se
+ \auxb=1% o y "sobe"
+ \or% para baixo "\pdown" (pointing down)
+ \auxa=0% x mant{\^e}m-se
+ \auxb=-1% o y "desce"
+ \or% para a direita "\pright" (pointing right)
+ \auxa=1% o x move-se para a direita
+ \auxb=0% o y mant{\^e}m-se
+ \or% para a esquerda "\pleft" (pointing left)
+ \auxa=-1% o x move-se para a esquerda
+ \auxb=0% o y mant{\^e}m-se
+ \fi % constru{\c c}{\~a}o do arco
+ \ifcase #6 % arco (com seta) s{\'o}lido
+ \modifplot#1% Desenhar o arco
+ % constru{\c c}{\~a}o da seta
+ \setaxy#1
+ \or % arco (com seta) a tracejado
+ \setdashes
+ \modifplot#1% Desenhar o arco
+ \setaxy#1
+ \setsolid
+ \or % arco sem seta
+ \modifplot#1% Desenhar o arco
+ \fi % seta de injec{\c c}{\~a}o
+%% coloca{\c c}{\~a}o da etiqueta do morfismo
+ \x=#3%
+ \y=#4%
+ \multiply \x by \expansao%
+ \multiply \y by \expansao%
+ \put {#5} at {\x} {\y}}
+
+%%
+%% Comando para construir os Objectos
+%% \obj(x,y){<texto>}[<etiqueta>]
+%%
+\def\obj(#1,#2){%
+ \!ifnextchar[{\!obja{#1}{#2}}{\!obja{#1}{#2}[Nulo]}}
+\def\!obja#1#2[#3]#4{%
+ \!ifnextchar[{\!objb{#1}{#2}{#3}{#4}}{\!objb{#1}{#2}{#3}{#4}[1]}}
+\def\!objb#1#2#3#4[#5]{%
+ \x=#1%
+ \y=#2%
+ \def\!pinta{\normalsize$\bullet$}% para definir o tamanho normal das pintas
+ \def\!nulo{Nulo}%
+ \def\!arg{#3}%
+ \!compara{\!arg}{\!nulo}%
+ \ifcompara\def\!arg{#4}\fi%
+ \multiply \x by \expansao%
+ \multiply \y by \expansao%
+ \setbox\caixa=\hbox{#4}%
+ \!coloca{(\!arg)(#1,#2)(\number\ht\caixa,\number\wd\caixa,\number\dp\caixa)}{\pilha}%
+ \auxa=\wd\caixa \divide \auxa by 131072
+ \advance \auxa by 5
+ \auxb=\ht\caixa
+ \advance \auxb by \number\dp\caixa
+ \divide \auxb by 131072
+ \advance \auxb by 5
+%(\number\auxa,
+%\number\auxb)
+% \aux=\ht\caixa \divide \auxa by 131072
+% \advance \auxa by 5
+% \auxb=\dp\caixa \divide \auxb by 131072
+% \advance \auxb by 8
+ \ifcase \tipografo % diagramas comutativos
+ \put{#4} at {\x} {\y}
+ \or % grafos dirigidos
+ \ifcase #5 % c=0
+ \put{#4} at {\x} {\y}
+ \or % n=1
+ \put{\!pinta} at {\x} {\y}
+ \advance \y by \number\auxb % height+depth+5
+ \put{#4} at {\x} {\y}
+ \or % ne=2
+ \put{\!pinta} at {\x} {\y}
+ \advance \auxa by -2 % para fazer o ajuste (imperfeito)
+ \advance \auxb by -2 % ao raio da circunferência de centro (x,y)
+ \advance \x by \number\auxa % width+5
+ \advance \y by \number\auxb % height+depth+5
+ \put{#4} at {\x} {\y}
+ \or % e=3
+ \put{\!pinta} at {\x} {\y}
+ \advance \x by \number\auxa % width+5
+ \put{#4} at {\x} {\y}
+ \or % se=4
+ \put{\!pinta} at {\x} {\y}
+ \advance \auxa by -2 % para fazer o ajuste (imperfeito)
+ \advance \auxb by -2 % ao raio da circunferência de centro (x,y)
+ \advance \x by \number\auxa % width+5
+ \advance \y by -\number\auxb % height+depth+5
+ \put{#4} at {\x} {\y}
+ \or % s=5
+ \put{\!pinta} at {\x} {\y}
+ \advance \y by -\number\auxb % height+depth+5
+ \put{#4} at {\x} {\y}
+ \or % sw=6
+ \put{\!pinta} at {\x} {\y}
+ \advance \auxa by -2 % para fazer o ajuste (imperfeito)
+ \advance \auxb by -2 % ao raio da circunferência de centro (x,y)
+ \advance \x by -\number\auxa % width+5
+ \advance \y by -\number\auxb % height+depth+5
+ \put{#4} at {\x} {\y}
+ \or % w=7
+ \put{\!pinta} at {\x} {\y}
+ \advance \x by -\number\auxa % width+5
+ \put{#4} at {\x} {\y}
+ \or % nw=8
+ \put{\!pinta} at {\x} {\y}
+ \advance \auxa by -2 % para fazer o ajuste (imperfeito)
+ \advance \auxb by -2 % ao raio da circunferência de centro (x,y)
+ \advance \x by -\number\auxa % width+5
+ \advance \y by \number\auxb % height+depth+5
+ \put{#4} at {\x} {\y}
+ \fi
+ \or % grafos não dirigidos
+ \ifcase #5 % c=0
+ \put{#4} at {\x} {\y}
+ \or % n=1
+ \put{\!pinta} at {\x} {\y}
+ \advance \y by \number\auxb % height+depth+5
+ \put{#4} at {\x} {\y}
+ \or % ne=2
+ \put{\!pinta} at {\x} {\y}
+ \advance \auxa by -2 % para fazer o ajuste (imperfeito)
+ \advance \auxb by -2 % ao raio da circunferência de centro (x,y)
+ \advance \x by \number\auxa % width+5
+ \advance \y by \number\auxb % height+depth+5
+ \put{#4} at {\x} {\y}
+ \or % e=3
+ \put{\!pinta} at {\x} {\y}
+ \advance \x by \number\auxa % width+5
+ \put{#4} at {\x} {\y}
+ \or % se=4
+ \put{\!pinta} at {\x} {\y}
+ \advance \auxa by -2 % ver acima
+ \advance \auxb by -2
+ \advance \x by \number\auxa % width+5
+ \advance \y by -\number\auxb % height+depth+5
+ \put{#4} at {\x} {\y}
+ \or % s=5
+ \put{\!pinta} at {\x} {\y}
+ \advance \y by -\number\auxb % height+depth+5
+ \put{#4} at {\x} {\y}
+ \or % sw=6
+ \put{\!pinta} at {\x} {\y}
+ \advance \auxa by -2 % ver acima
+ \advance \auxb by -2
+ \advance \x by -\number\auxa % width+5
+ \advance \y by -\number\auxb % height+depth+5
+ \put{#4} at {\x} {\y}
+ \or % w=7
+ \put{\!pinta} at {\x} {\y}
+ \advance \x by -\number\auxa % width+5
+ \put{#4} at {\x} {\y}
+ \or % nw=8
+ \put{\!pinta} at {\x} {\y}
+ \advance \auxa by -2 % ver acima
+ \advance \auxb by -2
+ \advance \x by -\number\auxa % width+5
+ \advance \y by \number\auxb % height+depth+5
+ \put{#4} at {\x} {\y}
+ \fi
+% \or % grafos dirigidos com molduras circulares nos objectos
+% \advance \auxa by 4
+% \put{\circle{\auxa}} [Bl] at {\x} {\y}
+% \put{#4} at {\x} {\y}
+% \or % grafos não dirigidos com molduras circulares nos objectos
+ \else % grafos com molduras circulares nos objectos
+ \ifnum\auxa<\auxb % determina a maior das dimensões
+ \aux=\auxb
+ \else
+ \aux=\auxa
+ \fi
+% se a largura da caixa é menor do que 1em então o tamanho
+% tamanho é ajustado para esse valor mínimo
+ \ifdim\wd\caixa<1em
+ \dimen99 = 1em
+ \aux=\dimen99 \divide \aux by 131072
+ \advance \aux by 5
+ \fi
+ \advance\aux by -2 %folga entre o objecto e a moldura
+ \multiply\aux by 2 %
+ \ifnum\aux<30
+ \put{\circle{\aux}} [Bl] at {\x} {\y}
+ \else
+ \multiply\auxa by 2
+ \multiply\auxb by 2
+ \put{\oval(\auxa,\auxb)} [Bl] at {\x} {\y}
+ \fi
+ \put{#4} at {\x} {\y}
+ \fi
+}
+
+
+\catcode`!=12 % ***** THIS MUST NEVER BE OMITTED (Ver PiCTeX)