From 35a5ddb9c4a7ab6239bc84741df4cbd8cf8e2ac9 Mon Sep 17 00:00:00 2001
From: Karl Berry <karl@freefriends.org>
Date: Thu, 31 Dec 2009 01:44:07 +0000
Subject: dcpic update (27dec09)

git-svn-id: svn://tug.org/texlive/trunk@16547 c570f23f-e606-0410-a88d-b1316a301751
---
 Master/texmf-dist/tex/generic/dcpic/dcpic.sty | 1378 +++++++++++++++++++++++++
 1 file changed, 1378 insertions(+)
 create mode 100644 Master/texmf-dist/tex/generic/dcpic/dcpic.sty

(limited to 'Master/texmf-dist/tex/generic/dcpic/dcpic.sty')

diff --git a/Master/texmf-dist/tex/generic/dcpic/dcpic.sty b/Master/texmf-dist/tex/generic/dcpic/dcpic.sty
new file mode 100644
index 00000000000..4c1ef123710
--- /dev/null
+++ b/Master/texmf-dist/tex/generic/dcpic/dcpic.sty
@@ -0,0 +1,1378 @@
+%% DC-PiCTeX
+%% Copyright (c) 1990-2009 Pedro Quaresma, Coimbra, Portugal
+%% 11/1990 (version 1.0); 
+%%   10/1991 (version 1.1);
+%%    9/1993 (version 1.2);  
+%%    3/1995 (version 1.3);
+%%  7/1996 (version 2.1);
+%%  5/2001 (version 3.0); 
+%%   11/2001 (version 3.1);
+%%    1/2002 (version 3.2)
+%%  5/2002 (version 4.0); 
+%%    3/2003 (version 4.1); 
+%%      12/2004 (version 4.1.1)
+%%    3/2007 (version 4.2)
+%%       5/2008 (version 4.2.1)
+%%    8/2008 (version 4.3)
+%%      12/2008 (version 4.3.1)
+%%      12/2009 (version 4.3.2)
+
+\immediate\write10{Package DCpic 2009/12/22 v4.3.2}
+
+\ProvidesPackage{dcpic}[2009/12/22 v4.3.2]
+
+%% Version X.Y.Z
+%%   X - major versions
+%%   Y - minor versions
+%%   Z - bug corrections
+%%
+%% Copyright (c) 1990-2009 Pedro Quaresma <pedro@mat.uc.pt>
+%%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+%   http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+% 
+% The Current Maintainer of this work is Pedro Quaresma (pedro@mat.uc.pt).
+%
+% This work consists of the files dcpic.sty.
+%%
+%% Coimbra, 22 de Dezembro de 2009 (2009/12/22)
+%% 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]
+%%        #1 - Graph type
+%%          0 = "commdiag" (commutative diagram)
+%%          1 = "digraph" (direct graph)
+%%          2 = "undigraph" (undirect graph)
+%%          3 = "cdigraph" with incircled objects
+%%          4 = "cundigraph" with incircled objects
+%%        (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
+%% (optional) #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 - coordinates (beginning)
+%%          #3 and #4 - coordinates (ending)
+%%(optional)#5,#6 - correction factors (defaul values, 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 = "\dashline"
+%%               4 = "\dotline"
+%%               5 = "\injectionarrow"   --- old value 3
+%%               6 = "\aplicationarrow"  --- old value 4
+%%               7 = "\surjectivearrow"  --- old value 5
+%%               8 = "\equalline" (thanks to Ruben Debeerst), 
+%%               9 = "\doublearrow" 
+%%              10 = "\doubleopposite" 
+%%              11 = "nullarrow" (to allow adding labels to existing arrows)
+%%
+%% Notes: the equalline "arrow" does not provide a second label.
+%%
+%% 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
+%%(optional)#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}
+%%-----------------//-------------
+%% Modifications (9/1993)
+%%       argument "distance" between de tip of the arrow and the objects
+%%       became optional; a new option for the "arrows" (option 3)
+%%
+%% 2/3/1995 (version 1.3) 
+%%       adds "the aplication arrow" (option 4); the distance between
+%%       the label and the "arrow" is now a fixed value (10 units).
+%% 15/7/1996 (version 2.1)
+%%       The comand "\mor" has a new sintax. The 5th and 6th
+%%       parameters are now the distance between the two objects and
+%%       the arrow tips. The 7th parameter is the label. The 8th e 9th
+%%       parameters (label position and type of arrow) are now optional
+%%
+%% 5/2001 (version 3.0)
+%%       Implementation of the comand "\cmor" based on the quadratic
+%%       curver comand of PiCTeX
+%%
+%% 11/2001 (version 3.1)
+%%       Changes on the tips of the arrow to became more LaTeX style
+%%       (after a conversation on EuroTeX 2001).
+%%
+%% 1/2002  (version 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 (version 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" (2), 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".
+%%
+%% 3/2003 (version 4.1)
+%%       Responding to a request of Jon Barker <jeb1@soton.ac.uk> I
+%%       create a new type of arrow, the surjective arrow.
+%%       For now only horizontal and vertical versions, other angles
+%%       are poorly rendered.
+%% 12/2004 (version 4.1.1)
+%%       New version for the surjective arrows, solve the problems
+%%       with the first implementation of this option.
+%% 3/2007 (version 4.2)
+%%       Adds the "providespackage" directive that was missing.
+%%       Adds dashed lines, and dotted lines.
+%% 5/2008 (version 4.2.1)
+%%       Deleting some counters, trying to avoid the problem "running
+%%       out of counters", that occurs because of the use of PiCTeX
+%%       and DCpic (only two...)
+%% 8/2008 (version 4.3)
+%%       Thanks to Ruben Debeerst (debeerst@mathematik.uni-kassel.de),
+%%       he added a new arrow "equalline". After that I
+%%       decided to add: the doublearrow; the doublearrow with
+%%       opposite directions; the null arrow. This last can be used as
+%%       a simple form of adding new labels.
+%%12/2008 (version 4.3.1)
+%%       The comand \id is internalised (\!id), it should be that way
+%%       from the begining because it is not to be used from the
+%%       outside.
+%%       The comand \dasharrow was changed to \dashArrow to avoid a
+%%       clash with the AMS command with the same name.
+%%12/2009 (version 4.3.2)
+%%       There is a conflict between dcpic.sty and hyperref in current
+%%        texlive-2009 due to the one letter macro \d (thanks Thorsten
+%%        S <thorsten.schwander@gmail.com>).
+%%        The \d changed to \deuc (Euclidian Distance). The \x and \y
+%%        changed to \xO \yO
+%%-----------------//-------------
+
+\catcode`!=11 %  ***** THIS MUST NEVER BE OMITTED (See PiCTeX)
+
+\newcount\aux%
+\newcount\auxa%
+\newcount\auxb%
+\newcount\xO%
+\newcount\yO%
+\newcount\xl%
+\newcount\yl%
+\newcount\deuc%
+\newcount\dnm%
+\newcount\xa%
+\newcount\xb%
+\newcount\xmed%
+\newcount\xc%
+\newcount\xd%
+\newcount\xe
+\newcount\xf
+\newcount\ya%
+\newcount\yb%
+\newcount\ymed%
+\newcount\yc%
+\newcount\yd
+\newcount\ye
+\newcount\yf
+%% "global variables"
+\newcount\expansao%
+\newcount\tipografo%       version 4.0
+\newcount\distanciaobjmor% version 4.0
+\newcount\tipoarco%        version 4.0
+%\newif\ifarredondada%        version 4.0 (initial value "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%
+%% for the triming 
+\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}}
+
+%% Private Macro
+%% Absolute Value)
+%% \absoluto{n}{absn}
+%% input
+%%  n - integer
+%% output
+%%  absn - |n|
+\def\!absoluto#1#2{\aux=#1%
+  \ifnum \aux > 0
+    #2=\aux
+  \else
+    \multiply \aux by -1
+    #2=\aux
+  \fi}
+
+
+%% Name definitions for edge types and directions
+\def\solidarrow{0}
+\def\dashArrow{1}
+\def\solidline{2}
+\def\dashline{3}
+\def\dotline{4}
+\def\injectionarrow{5}
+\def\aplicationarrow{6}
+\def\surjectivearrow{7}
+\def\equalline{8}
+\def\doublearrow{9}
+\def\doubleopposite{10}
+\def\nullarrow{11}
+
+%% 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}
+%% Positioning of labels in graphs
+\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\yO=\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\xO=\number\xl
+     \ifnum\number\yl>\number\yO
+%% 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=\xO
+     \advance\auxqx by -\xl
+     \!absoluto{\auxqx}{\auxqx}%
+     \auxqy=\yO
+     \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>\yO
+       \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{\auxa=#1%
+  \auxb=1%
+  \loop
+    \aux=\auxb%
+    \advance \aux by 1%
+    \multiply \aux by \aux%
+    \ifnum \aux < \auxa%
+      \advance \auxb by 1%
+      \paratrue%
+    \else\ifnum \aux=\auxa%
+      \advance \auxb by 1%
+      \paratrue%
+       \else\parafalse%
+       \fi
+    \fi
+  \ifpara%
+  \repeat
+#2=\auxb}
+
+%%Private Macro 
+%% Find the starting and ending points of the "arrow" and also the
+%% label position (one coordinate at a time)
+%% 
+%% ucoord{x1}{x2}{x3}{x4}{x5}{x6}{+|- 1}
+%% Input
+%%   x1,x2,x3,x4,x5
+%% Output
+%%   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}
+
+%%Private Macro
+%% Euclidean distance between two points
+%%
+%% quadrado{n}{m}{l}
+%% Input
+%%   n - natural number
+%%   m - natural number
+%% Output
+%%   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         % arrow
+    \tipografo=0        % commutative diagram
+  \or
+    \distanciaobjmor=2
+    \tipoarco=0         % arrow
+    \tipografo=1        % directed graph
+  \or
+    \distanciaobjmor=1
+    \tipoarco=2         % line
+    \tipografo=2        % undirected graph
+  \or
+    \distanciaobjmor=8
+    \tipoarco=0         % arrow 
+    \tipografo=3        % directed graph
+%    \arredondadotrue    % objectos com molduras circulares
+  \or
+    \distanciaobjmor=8
+    \tipoarco=2         % line
+    \tipografo=4        % undirected graph
+%    \arredondadotrue    % objectos com molduras circulares
+  \fi}
+
+\def\enddc{\endpicture}
+
+
+%% Public macro: "mor"
+%%
+%%
+%% Funtion to built the "arrow" between two points
+%%
+%% The points that are uses to built all the elements of the "arrows"
+%% are:
+%% 
+%%                (xc,yc)
+%%                   o
+%%                   |
+%%  o------o---------o---------o------o
+%%(x,y) (xa,ya)   (xm,ym)   (xb,yb)(xl,yl)
+%%
+%% auxa - distance between (x,y) and (xa,ya), 10pt by default
+%% auxb - distance between (xl,yl) and (xb,yb), 10pt by default
+%%
+\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%
+%%
+%% error message and ficticious parameters
+%%
+   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{%
+  \xO=#1
+  \yO=#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%
+%%
+%% error message and ficticious parameters
+%%
+   Error: Incorrect label specification
+   \xaux=\xO%
+   \advance\xaux by \xO%
+   \yaux=\yO%
+   \advance\yaux by \yO%
+  \fi
+ \fi
+ \let\pilha=\pilhaaux
+ \!ifnextchar[{\!mora{\number\xO}{\number\yO}{\number\xaux}{\number\yaux}}{\!mora{\number\xO}{\number\yO}{\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]{\xO=#1%
+  \yO=#2%
+  \xl=#3%
+  \yl=#4%
+  \multiply \xO by \expansao%
+  \multiply \yO by \expansao%
+  \multiply \xl by \expansao%
+  \multiply \yl by \expansao%
+%%
+%% Euclidean distance between two points
+%% d = \sqrt((x-xl)^2+(y-yl)^2)
+%%
+  \!quadrado{\number\xO}{\number\xl}{\auxa}%
+  \!quadrado{\number\yO}{\number\yl}{\auxb}%
+  \deuc=\auxa%
+  \advance \deuc by \auxb%
+  \!raiz{\deuc}{\deuc}%
+%%
+%% the point (xa,ya) is at a distance #5 (default value 10) from the
+%% point (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{\xO}{\xl}{\yO}{\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\xO}{\number\xl}{\number\xO}{\auxa}{\number\deuc}{\xa}{1}%
+  \!ucoord{\number\yO}{\number\yl}{\number\yO}{\auxa}{\number\deuc}{\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=\deuc%
+%%
+%% the point (xb,yb) is at a distance #6 (default value 10) from the
+%% point (xl,yl)
+%%
+  \auxb=#6
+  \!compara{\objNulo}{\objChegada}%
+  \ifdiferentes% S{\'o} vai fazer o ajuste quando {\'e} necess{\'a}rio
+%   Vou ajustar
+   \!ajusta{\xO}{\xl}{\yO}{\yl}{\auxb}{\objChegada}%
+   \def\objChegada{}% re-inicializar o valor do Objecto de Chegada
+  \fi
+  \advance \auxa by -\auxb%
+  \!ucoord{\number\xO}{\number\xl}{\number\xO}{\number\auxa}{\number\deuc}{\xb}{1}%
+  \!ucoord{\number\yO}{\number\yl}{\number\yO}{\number\auxa}{\number\deuc}{\yb}{1}%
+  \xmed=\xa%
+  \advance \xmed by \xb%
+  \divide \xmed by 2
+  \ymed=\ya%
+  \advance \ymed by \yb%
+  \divide \ymed by 2
+%%
+%% find the coordinates of the label position: (xc,yc)
+%%
+%% after this the values of xmed and ymed are no longer important
+%%
+  \!distnomemor{\number\xO}{\number\yO}{\number\xl}{\number\yl}{#7}{\dnm}%
+  \!ucoord{\number\yO}{\number\yl}{\number\xmed}{\number\dnm}{\number\deuc}{\xc}{-#8}% 
+  \!ucoord{\number\xO}{\number\xl}{\number\ymed}{\number\dnm}{\number\deuc}{\yc}{#8}%
+%% 
+%% draw the "arrow"
+%%
+\ifcase #9            % 0=solid arrow
+  \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
+\or                   % 1=dashed arrow
+  \setdashes
+  \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
+  \setsolid
+\or                   % 2=solid line
+  \setlinear
+  \plot {\xa} {\ya}  {\xb} {\yb} /
+\or                   % 3=dashed line
+  \setdashes
+  \setlinear
+  \plot {\xa} {\ya}  {\xb} {\yb} /
+  \setsolid
+\or                   % 4=dotted line
+  \setdots
+  \setlinear
+  \plot {\xa} {\ya}  {\xb} {\yb} /
+  \setsolid
+\or                   % 5=injective arrow
+%% C{\'a}lculos auxiliares
+%%
+%% 3 units, the radius for the tail of the arrow
+%%
+%% repor o valor de auxa
+  \auxa=\guardaauxa
+%% dar a compensa{\c c}{\~a}o para o "rabo"
+  \advance \auxa by 3%
+%%
+%% Note: the values of (xa,ya) will be modified, they will be
+%% "pushed" further away from (x,y) in order to acomodate the tail
+%% of the "arrow"
+%%
+%% find the point (xd,yd), the center of a 3pt circle
+%%
+ \!ucoord{\number\xO}{\number\xl}{\number\xO}{\number\auxa}{\number\deuc}{\xa}{1}%
+ \!ucoord{\number\yO}{\number\yl}{\number\yO}{\number\auxa}{\number\deuc}{\ya}{1}%
+ \!ucoord{\number\yO}{\number\yl}{\number\xa}{3}{\number\deuc}{\xd}{-1}%
+ \!ucoord{\number\xO}{\number\xl}{\number\ya}{3}{\number\deuc}{\yd}{1}%
+%% building the "arrow"
+  \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
+%% and its "tail"
+  \circulararc -180 degrees from {\xa} {\ya} center at {\xd} {\yd}
+\or                   % 6=maps "arrow" ("|-->")
+  \auxa=3
+%%
+%% Note: the values of xmed and ymed will be modified
+%% 
+%% find the two points that defines the tail of the arrow (segment
+%% (xmed,ymed)(xd,yd))
+ \!ucoord{\number\yO}{\number\yl}{\number\xa}{\number\auxa}{\number\deuc}{\xmed}{-1}%
+ \!ucoord{\number\xO}{\number\xl}{\number\ya}{\number\auxa}{\number\deuc}{\ymed}{1}%
+ \!ucoord{\number\yO}{\number\yl}{\number\xa}{\number\auxa}{\number\deuc}{\xd}{1}%
+ \!ucoord{\number\xO}{\number\xl}{\number\ya}{\number\auxa}{\number\deuc}{\yd}{-1}%
+%% building the "arrow"
+  \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
+%% and its "tail"
+  \setlinear
+  \plot {\xmed} {\ymed}  {\xd} {\yd} /
+\or                   % 7=surjective arrow ("-->>")
+%% building arrow with the first tip
+  \arrow <4pt> [.2,1.1] from {\xa} {\ya} to {\xb} {\yb}
+%% and the second tip
+  \setlinear
+  \arrow <6pt> [0,.72] from {\xa} {\ya} to {\xb} {\yb}
+\or                   % 8=equalline
+%% by Ruben Debeerst: equal-line
+%%
+%% sets the separation (distance) between the two parallel lines, if
+%% horizontal or vertical 1pt is enough, if not 2pt
+\auxa=2
+\ifnum\number\yO=\number\yl
+\auxa=1
+\fi
+\ifnum\number\xO=\number\xl
+\auxa=1
+\fi
+%% the two parallel lines will be given by (xmed,ymed)(xd,yd), and
+%% (xe,ye)(xf,yf)
+  \!ucoord{\number\yO}{\number\yl}{\number\xa}{\number\auxa}{\number\deuc}{\xmed}{-1}%
+  \!ucoord{\number\xO}{\number\xl}{\number\ya}{\number\auxa}{\number\deuc}{\ymed}{1}%
+  \!ucoord{\number\yO}{\number\yl}{\number\xa}{\number\auxa}{\number\deuc}{\xd}{1}%
+  \!ucoord{\number\xO}{\number\xl}{\number\ya}{\number\auxa}{\number\deuc}{\yd}{-1}%
+  
+  \!ucoord{\number\yO}{\number\yl}{\number\xb}{\number\auxa}{\number\deuc}{\xe}{-1}%
+  \!ucoord{\number\xO}{\number\xl}{\number\yb}{\number\auxa}{\number\deuc}{\ye}{1}%
+  \!ucoord{\number\yO}{\number\yl}{\number\xb}{\number\auxa}{\number\deuc}{\xf}{1}%
+  \!ucoord{\number\xO}{\number\xl}{\number\yb}{\number\auxa}{\number\deuc}{\yf}{-1}%
+  \setlinear
+  \plot {\xmed} {\ymed}  {\xe} {\ye} /
+  \plot {\xd} {\yd}  {\xf} {\yf} /
+\or                   % 9=double arrow  
+%% 
+%% sets the separation (distance) between the two parallel lines, if
+%% horizontal or vertical 2pt is enough, if not 3pt. The extra space
+%% is needed because of the arrow tip.
+\auxa=3
+\ifnum\number\yO=\number\yl
+\auxa=2
+\fi
+\ifnum\number\xO=\number\xl
+\auxa=2
+\fi
+%% the two parallel lines will be given by (xmed,ymed)(xd,yd), and
+%% (xe,ye)(xf,yf)
+  \!ucoord{\number\yO}{\number\yl}{\number\xa}{\number\auxa}{\number\deuc}{\xmed}{-1}%
+  \!ucoord{\number\xO}{\number\xl}{\number\ya}{\number\auxa}{\number\deuc}{\ymed}{1}%
+  \!ucoord{\number\yO}{\number\yl}{\number\xa}{\number\auxa}{\number\deuc}{\xd}{1}%
+  \!ucoord{\number\xO}{\number\xl}{\number\ya}{\number\auxa}{\number\deuc}{\yd}{-1}%
+  
+  \!ucoord{\number\yO}{\number\yl}{\number\xb}{\number\auxa}{\number\deuc}{\xe}{-1}%
+  \!ucoord{\number\xO}{\number\xl}{\number\yb}{\number\auxa}{\number\deuc}{\ye}{1}%
+  \!ucoord{\number\yO}{\number\yl}{\number\xb}{\number\auxa}{\number\deuc}{\xf}{1}%
+  \!ucoord{\number\xO}{\number\xl}{\number\yb}{\number\auxa}{\number\deuc}{\yf}{-1}%
+  \arrow <4pt> [.2,1.1] from {\xmed} {\ymed} to {\xe} {\ye}
+  \arrow <4pt> [.2,1.1] from {\xd} {\yd} to {\xf} {\yf}
+\or                   % 10=double arrow, opposite directions
+%% 
+%% sets the separation (distance) between the two parallel lines, if
+%% horizontal or vertical 2pt is enough, if not 3pt. The extra space
+%% is needed because of the arrow tip.
+\auxa=3
+\ifnum\number\yO=\number\yl
+\auxa=2
+\fi
+\ifnum\number\xO=\number\xl
+\auxa=2
+\fi
+%% the two parallel lines will be given by (xmed,ymed)(xd,yd), and
+%% (xe,ye)(xf,yf)
+  \!ucoord{\number\yO}{\number\yl}{\number\xa}{\number\auxa}{\number\deuc}{\xmed}{-1}%
+  \!ucoord{\number\xO}{\number\xl}{\number\ya}{\number\auxa}{\number\deuc}{\ymed}{1}%
+  \!ucoord{\number\yO}{\number\yl}{\number\xa}{\number\auxa}{\number\deuc}{\xd}{1}%
+  \!ucoord{\number\xO}{\number\xl}{\number\ya}{\number\auxa}{\number\deuc}{\yd}{-1}%
+  
+  \!ucoord{\number\yO}{\number\yl}{\number\xb}{\number\auxa}{\number\deuc}{\xe}{-1}%
+  \!ucoord{\number\xO}{\number\xl}{\number\yb}{\number\auxa}{\number\deuc}{\ye}{1}%
+  \!ucoord{\number\yO}{\number\yl}{\number\xb}{\number\auxa}{\number\deuc}{\xf}{1}%
+  \!ucoord{\number\xO}{\number\xl}{\number\yb}{\number\auxa}{\number\deuc}{\yf}{-1}%
+  \arrow <4pt> [.2,1.1] from {\xmed} {\ymed} to {\xe} {\ye}
+  \arrow <4pt> [.2,1.1] from {\xf} {\yf} to {\xd} {\yd}
+\or                   % 11=null arrow (no arrow, only a label)
+%%
+%% does not draw the arrow, it allows to put two labels in one "arrow"
+%%
+\fi
+%% The label positioning.
+%% 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 -\xO%
+\ifnum \auxa=0 
+  \put {#7} at {\xc} {\yc}
+\else
+  \auxb=\yl
+  \advance \auxb by -\yO%
+  \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){\xO=#1%
+  \yO=#2%
+  \multiply \xO by \expansao%
+  \multiply \yO by \expansao%
+  \!start (\xO,\yO)
+  \!modifQjoin}
+\def\!modifQjoin(#1,#2)(#3,#4){\xO=#1%
+  \yO=#2%
+  \xl=#3%
+  \yl=#4%
+  \multiply \xO by \expansao%
+  \multiply \yO by \expansao%
+  \multiply \xl by \expansao%
+  \multiply \yl by \expansao%
+  \!qjoin (\xO,\yO) (\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){\xO=#1%
+  \yO=#2
+  \multiply \xO by \expansao
+  \multiply \yO by \expansao
+  \xl=\xO%
+  \yl=\yO%
+  \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 {\xO} {\yO} 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
+  \xO=#3%  
+  \yO=#4%
+  \multiply \xO by \expansao%
+  \multiply \yO by \expansao%
+  \put {#5} at {\xO} {\yO}}
+
+%%
+%% 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]{%
+  \xO=#1%
+  \yO=#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 \xO by \expansao%
+  \multiply \yO 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 {\xO} {\yO}
+  \or                   % grafos dirigidos
+    \ifcase #5 % c=0
+      \put{#4} at {\xO} {\yO}
+    \or        % n=1
+      \put{\!pinta} at {\xO} {\yO}
+      \advance \yO by \number\auxb  % height+depth+5
+      \put{#4} at {\xO} {\yO}
+    \or        % ne=2
+      \put{\!pinta} at {\xO} {\yO}
+      \advance \auxa by -2  % para fazer o ajuste (imperfeito)
+      \advance \auxb by -2  % ao raio da circunferencia de centro (x,y)
+      \advance \xO by \number\auxa  % width+5
+      \advance \yO by \number\auxb  % height+depth+5
+      \put{#4} at {\xO} {\yO}   
+    \or        % e=3
+      \put{\!pinta} at {\xO} {\yO}
+      \advance \xO by \number\auxa  % width+5
+      \put{#4} at {\xO} {\yO}   
+    \or        % se=4
+      \put{\!pinta} at {\xO} {\yO}
+      \advance \auxa by -2  % para fazer o ajuste (imperfeito)
+      \advance \auxb by -2  % ao raio da circunferencia de centro (x,y)
+      \advance \xO by \number\auxa  % width+5
+      \advance \yO by -\number\auxb  % height+depth+5
+      \put{#4} at {\xO} {\yO}   
+    \or        % s=5
+      \put{\!pinta} at {\xO} {\yO}
+      \advance \yO by -\number\auxb  % height+depth+5
+      \put{#4} at {\xO} {\yO}   
+    \or        % sw=6
+      \put{\!pinta} at {\xO} {\yO}
+      \advance \auxa by -2  % para fazer o ajuste (imperfeito)
+      \advance \auxb by -2  % ao raio da circunferencia de centro (x,y)
+      \advance \xO by -\number\auxa  % width+5
+      \advance \yO by -\number\auxb  % height+depth+5
+      \put{#4} at {\xO} {\yO}   
+    \or        % w=7
+      \put{\!pinta} at {\xO} {\yO}
+      \advance \xO by -\number\auxa  % width+5
+      \put{#4} at {\xO} {\yO}   
+    \or        % nw=8
+      \put{\!pinta} at {\xO} {\yO}
+      \advance \auxa by -2  % para fazer o ajuste (imperfeito)
+      \advance \auxb by -2  % ao raio da circunferencia de centro (x,y)
+      \advance \xO by -\number\auxa  % width+5
+      \advance \yO by \number\auxb  % height+depth+5
+      \put{#4} at {\xO} {\yO}   
+    \fi
+  \or                   % grafos nao dirigidos
+    \ifcase #5 % c=0
+      \put{#4} at {\xO} {\yO}
+    \or        % n=1
+      \put{\!pinta} at {\xO} {\yO}
+      \advance \yO by \number\auxb  % height+depth+5
+      \put{#4} at {\xO} {\yO}
+    \or        % ne=2
+      \put{\!pinta} at {\xO} {\yO}
+      \advance \auxa by -2  % para fazer o ajuste (imperfeito)
+      \advance \auxb by -2  % ao raio da circunferencia de centro (x,y)
+      \advance \xO by \number\auxa  % width+5
+      \advance \yO by \number\auxb  % height+depth+5
+      \put{#4} at {\xO} {\yO}   
+    \or        % e=3
+      \put{\!pinta} at {\xO} {\yO}
+      \advance \xO by \number\auxa  % width+5
+      \put{#4} at {\xO} {\yO}   
+    \or        % se=4
+      \put{\!pinta} at {\xO} {\yO}
+      \advance \auxa by -2  % ver acima
+      \advance \auxb by -2
+      \advance \xO by \number\auxa  % width+5
+      \advance \yO by -\number\auxb % height+depth+5
+      \put{#4} at {\xO} {\yO}   
+    \or        % s=5
+      \put{\!pinta} at {\xO} {\yO}
+      \advance \yO by -\number\auxb % height+depth+5
+      \put{#4} at {\xO} {\yO}   
+    \or        % sw=6
+      \put{\!pinta} at {\xO} {\yO}
+      \advance \auxa by -2  % ver acima
+      \advance \auxb by -2
+      \advance \xO by -\number\auxa % width+5
+      \advance \yO by -\number\auxb % height+depth+5
+      \put{#4} at {\xO} {\yO}   
+    \or        % w=7
+      \put{\!pinta} at {\xO} {\yO}
+      \advance \xO by -\number\auxa % width+5
+      \put{#4} at {\xO} {\yO}   
+    \or        % nw=8
+      \put{\!pinta} at {\xO} {\yO}
+      \advance \auxa by -2  % ver acima
+      \advance \auxb by -2
+      \advance \xO by -\number\auxa % width+5
+      \advance \yO by \number\auxb  % height+depth+5
+      \put{#4} at {\xO} {\yO}   
+    \fi
+%  \or % grafos dirigidos com molduras circulares nos objectos
+%    \advance \auxa by 4
+%    \put{\circle{\auxa}} [Bl] at {\xO} {\yO}
+%    \put{#4} at {\xO} {\yO}
+%  \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 {\xO} {\yO}
+     \else
+       \multiply\auxa by 2
+       \multiply\auxb by 2
+       \put{\oval(\auxa,\auxb)} [Bl] at {\xO} {\yO}
+     \fi
+     \put{#4} at {\xO} {\yO}
+   \fi   
+}
+
+
+\catcode`!=12 %  *****  THIS MUST NEVER BE OMITTED (see PiCTeX)
-- 
cgit v1.2.3

