Skip to content

Commit

Permalink
Start rewrite as a TikZ library
Browse files Browse the repository at this point in the history
  • Loading branch information
hmenke committed May 22, 2022
1 parent 337b0ab commit 1d4a880
Show file tree
Hide file tree
Showing 3 changed files with 407 additions and 358 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:

strategy:
matrix:
engine: [pdflatex, xelatex, latex]
engine: [pdflatex, lualatex, xelatex, latex]

steps:
- uses: actions/checkout@v2
Expand Down
361 changes: 4 additions & 357 deletions tex/latex/pgf-umlcd/pgf-umlcd.sty
Original file line number Diff line number Diff line change
@@ -1,364 +1,11 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Start of pgf-umlcd.sty
%
% Some macros for UML Class Diagrams.
% Home page of project: http://pgf-umlcd.googlecode.com/
% Author: Xu Yuan <[email protected]>, Humboldt University, Berlin
% Style from: http://www.ibm.com/developerworks/cn/rational/r-uml/
%

% SPDX-License-Identifier: GPL-2.0-only OR LPPL-1.3c
\NeedsTeXFormat{LaTeX2e}[1999/12/01]
\ProvidesPackage{pgf-umlcd}[2011/10/01 v0.3dev Some LaTeX macros for
UML Class Diagrams.]

\RequirePackage{tikz}
\usetikzlibrary{umlcd}

\usetikzlibrary{arrows,shapes.multipart,backgrounds,fit}
\tikzstyle{help lines}+=[blue!50,very thin,dashed]

\newcommand{\umltextcolor}{black}
\newcommand{\umldrawcolor}{purple}
\newcommand{\umlfillcolor}{yellow!20}
\tikzstyle{umlcolor}=[color=\umldrawcolor,fill=\umlfillcolor,text=\umltextcolor]
\tikzstyle{umlcd style}=[umlcolor, >=angle 90]

\tikzstyle{package}=[matrix, column sep=1mm, row sep=1cm, node distance=2cm]
\tikzstyle{packagename}=[rectangle, minimum height=2em]

\tikzstyle{umlcd style implement line}=[color=\umldrawcolor, open triangle 45-,dashed]
\tikzstyle{objectline}=[color=\umldrawcolor, diamond->]
\tikzstyle{umlcd style inherit line}=[color=\umldrawcolor, open triangle 45-]
\tikzstyle{splitline}=[color=\umldrawcolor, dotted,font=\itshape]

\tikzstyle{umlcd style class}=[rectangle split, rectangle split parts=3,
every text node part/.style={text centered},
draw, minimum height=2em, umlcolor, minimum width=2cm, text width=5cm,
minimum height=1cm, node distance=2cm]


\tikzstyle{umlcd style dashed line}=[color=\umldrawcolor, >=angle 90,dashed]

\tikzstyle{umlcd style school}=[]
\newif\ifschool\schoolfalse
\DeclareOption{school}{\tikzstyle{umlcd style school}=[rounded corners] \schooltrue}
\newif\ifsimplified\simplifiedfalse
\DeclareOption{simplified}{\simplifiedtrue}
\DeclareOption{school}{\tikzset{umlcd style school/.style={rounded corners}}\pgfumlcd@schooltrue}
\DeclareOption{simplified}{\pgfumlcd@simplifiedtrue}
\ProcessOptions\relax


% declare layers
\pgfdeclarelayer{background}
\pgfdeclarelayer{connectionlayers}
\pgfsetlayers{background,connectionlayers,main}

\newcounter{umlcdClassAttributesNum}
\newcounter{umlcdClassOperationsNum}
\newcounter{umlcdClassAbstractClassNum}
\newcounter{umlcdClassInterfaceNum}
\newcounter{umlcdClassSplitPartNum}

\def\umlcdPackageFit{}

\newenvironment{class}[3][]%
{
\begin{classAndInterfaceCommon}{#1}{#2}{#3}
}%
{\calcuateNumberOfParts{}
\node[anchor=north, this umlcd style] (\umlcdClassName) at (\umlcdClassPos)
{\textbf{\umlcdClassName}
\insertAttributesAndOperations{}
};

\end{classAndInterfaceCommon}
}

\newenvironment{interface}[3][]%
{
\begin{classAndInterfaceCommon}{#1}{#2}{#3}
}%
{\calcuateNumberOfParts{}
\node[anchor=north,this umlcd style] (\umlcdClassName) at (\umlcdClassPos)
{$<<$interface$>>$ \\ \textbf{\umlcdClassName}
\insertAttributesAndOperations{}
};

\end{classAndInterfaceCommon}
}

\newenvironment{abstractclass}[3][]%
{
\begin{classAndInterfaceCommon}{#1}{#2}{#3}
}%
{\calcuateNumberOfParts{}
\node[anchor=north, this umlcd style] (\umlcdClassName) at (\umlcdClassPos)
{$<<$abstract$>>$ \\ \textbf{\umlcdClassName}
\insertAttributesAndOperations{}
};

\end{classAndInterfaceCommon}
}

\newenvironment{staticclass}[3][]%
{
\begin{classAndInterfaceCommon}{#1}{#2}{#3}
}%
{\calcuateNumberOfParts{}
\node[this umlcd style, anchor=north] (\umlcdClassName) at (\umlcdClassPos)
{$<<$static$>>$ \\ \textbf{\umlcdClassName}
\insertAttributesAndOperations{}
};

\end{classAndInterfaceCommon}
}

% TODO: here the name of \umlcdClassName and \umlObjectName should be
% switched, it is only for reusing \classAndInterfaceCommon at the
% moment.
\newenvironment{object}[3][]%
{
\begin{classAndInterfaceCommon}{#1}{#2}{#3}
\def\@instanceOf{}
\def\@@instanceOf{}
}%
{
% customized
\ifsimplified
\calcuateNumberOfParts{}
\else
\ifnum\c@umlcdClassOperationsNum>0
\setcounter{umlcdClassSplitPartNum}{3}
\protected@xdef\umlcdSplitPart{3}
\else
\setcounter{umlcdClassSplitPartNum}{2}
\protected@xdef\umlcdSplitPart{2}
\fi
\fi

\ifx\@instanceOf\@@instanceOf
\def\umldObjectName{\umlcdClassName}
\else
\def\umldObjectName{\umlcdClassName : \@instanceOf}
\fi

\node[anchor=north, this umlcd style, umlcd style school] (\umlcdClassName) at (\umlcdClassPos)
{ \ifschool
\textbf{\umldObjectName}
\else
\underline{\textbf{\umldObjectName}}
\fi
\insertAttributesAndOperations{}
};

\end{classAndInterfaceCommon}
}

\newcommand*{\insertAttributesAndOperations}
{
\ifnum\c@umlcdClassSplitPartNum>1
\nodepart{second}
\fi
\umlcdClassAttributes
\ifnum\c@umlcdClassSplitPartNum>2
\nodepart{third}
\fi
\umlcdClassOperations
}

\newcommand*{\calcuateNumberOfParts}
{
% calcuate the number of parts
\ifsimplified
\setcounter{umlcdClassSplitPartNum}{1}
\ifnum\c@umlcdClassAttributesNum>0
\stepcounter{umlcdClassSplitPartNum}
\fi
\ifnum\c@umlcdClassOperationsNum>0
\stepcounter{umlcdClassSplitPartNum}
\fi
\else
\setcounter{umlcdClassSplitPartNum}{3}% three parts by default
\fi

\protected@xdef\umlcdSplitPart{3}
\ifnum\c@umlcdClassSplitPartNum=1
\protected@xdef\umlcdSplitPart{1}
\fi
\ifnum\c@umlcdClassSplitPartNum=2
\protected@xdef\umlcdSplitPart{2}
\fi
}

\newenvironment*{classAndInterfaceCommon}[3]
{
\def\umlcdClassName{#2}%
\def\umlcdClassPos{#3}
\def\umlcdClassAttributes{}%
\def\umlcdClassOperations{}%
\def\umlcdClassAbstractClass{}%
\def\umlcdClassInterface{}%
\setcounter{umlcdClassAttributesNum}{0}%
\setcounter{umlcdClassOperationsNum}{0}%
\setcounter{umlcdClassAbstractClassNum}{0}%
\setcounter{umlcdClassInterfaceNum}{0}%
\tikzstyle{this umlcd style}=[umlcd style class, rectangle split
parts=\umlcdSplitPart, #1]
}%
{
%% connections
\begin{pgfonlayer}{connectionlayers}
\ifnum\c@umlcdClassAbstractClassNum>0
\foreach \c in \umlcdClassAbstractClass {
\draw [umlcd style inherit line] (\c) -- (\umlcdClassName);
}
\fi

\ifnum\c@umlcdClassInterfaceNum>0
\foreach \c in \umlcdClassInterface {
\draw [umlcd style implement line] (\c) -- (\umlcdClassName);
}
\fi
\end{pgfonlayer}

%% add to fit
\let\umlcdPackageFitOld\umlcdPackageFit
\protected@xdef\umlcdPackageFit{\umlcdPackageFitOld (\umlcdClassName)}
}

\newcommand{\attribute}[1]{%
\ifnum\c@umlcdClassAttributesNum=0
\protected@xdef\umlcdClassAttributes{#1}
\else
\let\umlcdClassAttributesOld\umlcdClassAttributes
\protected@xdef\umlcdClassAttributes{\umlcdClassAttributesOld \ \newline
#1}
\fi
\stepcounter{umlcdClassAttributesNum}
}

\newcommand{\operation}[2][1]{%
\stepcounter{umlcdClassOperationsNum}

\def\virtualoperation{#2}
\ifnum0=#1
\def\virtualoperation{\textit{#2}}
\fi

\ifnum\c@umlcdClassOperationsNum=1
\protected@xdef\umlcdClassOperations{\virtualoperation}
\else
\let\umlcdClassOperationsOld\umlcdClassOperations
\protected@xdef\umlcdClassOperations{\umlcdClassOperationsOld \ \newline
\virtualoperation}
\fi
}

\newcommand{\inherit}[1]
{
\stepcounter{umlcdClassAbstractClassNum}
\ifnum\c@umlcdClassAbstractClassNum=1
\protected@xdef\umlcdClassAbstractClass{#1}
\else
\let\umlcdClassAbstractClassOld\umlcdClassAbstractClass
\protected@xdef\umlcdClassAbstractClass{\umlcdClassAbstractClassOld,
#1}
\fi
}

\newcommand{\implement}[1]
{
\stepcounter{umlcdClassInterfaceNum}
\ifnum\c@umlcdClassInterfaceNum=1
\protected@xdef\umlcdClassInterface{#1}
\else
\let\umlcdClassInterfaceOld\umlcdClassInterface
\protected@xdef\umlcdClassInterface{\umlcdClassInterfaceOld,
#1}
\fi
}

\newcommand{\instanceOf}[1]{\def\@instanceOf{#1}}

\newcommand{\association}[7][]{
\draw [umlcd style,#1] (#2) -- (#5)
node[near start, auto]{#3}
node[near start, auto, swap]{#4}
node[near end, auto]{#6}
node[near end, auto, swap]{#7};
}

\newcommand{\unidirectionalAssociation}[5][]{
\draw [umlcd style, ->, #1] (#2) -- (#5)
node[near end, auto]{#3}
node[near end, auto, swap]{#4};
}

\newcommand{\aggregation}[5][]{
\draw[umlcd style, open diamond->, #1] (#2) -- (#5)
node[near end, auto]{#3}
node[near end, auto, swap]{#4};
}

\newcommand{\composition}[5][]{
\draw[umlcd style, fill=\umldrawcolor, diamond->, #1] (#2) -- (#5)
node[near end, auto]{#3}
node[near end, auto, swap]{#4};
}

\newenvironment{package}[1]{
\def\umlcdPackageFit{}
\def\umlcdPackageName{#1}
}{
\begin{pgfonlayer}{background}
\node[umlcd style, draw, inner sep=0.5cm, fit = \umlcdPackageFit] (\umlcdPackageName) {};
\node[umlcd style, draw, outer ysep=-0.5, anchor=south west] (\umlcdPackageName caption) at
(\umlcdPackageName.north west) {\umlcdPackageName};
\end{pgfonlayer}
}

\newcommand{\switchUmlcdSchool}{
\ifschool
\tikzstyle{umlcd style school}=[]
\schoolfalse
\else
\tikzstyle{umlcd style school}=[rounded corners]
\schooltrue
\fi
}

\pgfdeclareshape{umlcdnote}{
\inheritsavedanchors[from=rectangle] % this is nearly a rectangle
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{east}
% ... and possibly more
\backgroundpath{% this is new
% store lower right in xa/ya and upper right in xb/yb
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
% compute corner of flipped page
\pgf@xc=\pgf@xb \advance\pgf@xc by-10pt % this should be a parameter
\pgf@yc=\pgf@yb \advance\pgf@yc by-10pt
% construct main path
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
\pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
\pgfpathclose
% add little corner
\pgfpathmoveto{\pgfpoint{\pgf@xc}{\pgf@yb}}
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
\pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
}
}

\newcommand{\umlnote}[1][]{
\node[umlcd style, anchor=north, draw,shape=umlcdnote, text width=4cm, #1]
}

%%% End of pgf-umlcd.sty
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Loading

0 comments on commit 1d4a880

Please sign in to comment.