-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsopra-requirements.sty
231 lines (200 loc) · 11 KB
/
sopra-requirements.sty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
% sopra-requirements.sty
% Version: 1.0
% Author: Florian Sihler, 03.12.2019
% Will contain all the definitions to easily typeset and reference
% Functional-, Qualitative- and other Requirements.
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{sopra-requirements}[2019/12/03 EagleoutIce - requirements for the sopra-team-020]
% Lengths and Registers
\newcounter{sorversion} \setcounter{sorversion}{1009}
\newcounter{sor@counter@functional@requirement}%
\newcounter{sor@counter@quality@requirement}%
\newlength{\sor@length@list@compensation}%
\setlength\sor@length@list@compensation{-.5\baselineskip}
\def\sor@table@headerstyle{\color{white}}
% expected keys for the requirements:
\def\@sor@fnctl{functional} % => \sor@functional@requirementprefix
\def\@sor@qltl{quality} % => \sor@quality@requirementprefix
\def\@sor@currequirementprefix{}
\def\sor@functional@requirementprefix{FA}
\def\sor@quality@requirementprefix{QA}
\newif\ifsor@usetabu@ % we can use regular tabular - if tabu won't work.
\newif\ifsor@intoc@ % it is posible to place the reqs in the toc
\newif\ifsor@showtag@ % should the nametag be shown?
\newif\ifsor@showall@ % should all fields be shown?
% allow debug-options :D
\DeclareOption{usetabu}{\sor@usetabu@true}
\DeclareOption{notabu}{\sor@usetabu@false}
\DeclareOption{intoc}{\sor@intoc@true}
\DeclareOption{notoc}{\sor@intoc@false}
\DeclareOption{showtag}{\sor@showtag@true}
\DeclareOption{noshowtag}{\sor@showtag@false}
\DeclareOption{showallfields}{\sor@showall@true}
\DeclareOption{noshowallfields}{\sor@showall@false}
\ExecuteOptions{usetabu,intoc,showtag}%
\ProcessOptions\relax
\ifsor@usetabu@ \RequirePackage{tabu} \RequirePackage{colortbl} \else \RequirePackage{booktabs} \fi
\RequirePackage{makecell,longtable,xcolor,environ,amssymb,etoolbox,fontawesome,hyperref}
% New Columns
\newcolumntype{K}{p{.175\linewidth}}% 'Key'-column
\newcolumntype{V}{p{.725\linewidth}}% 'Value'-column
% Color Definitions
\@ifundefined{thesobversion}{% not called from sopra-base-class
\colorlet{HeaderColor}{purple}
\colorlet{NextHeaderColor}{purple!75!white}
}{% we will use the secondary/akzent color as default
\colorlet{HeaderColor}{sob@col@uulm@akzent}
\colorlet{NextHeaderColor}{sob@col@uulm@akzent!75!white}
}
% Fixes for the tabu-package
\ifsor@usetabu@
\def\tabu@classz{\tabu@classzORI}
\def\tabu@ignorehfil{\tabu@nohfil}
\fi
% Define the Header and next-header commands
\ifsor@usetabu@
\def\sor@table@headerrow{%
\rowfont{\normalfont\bfseries\leavevmode\sor@table@headerstyle}%
\rowcolor{HeaderColor}\@ifstar{}{\Gape[.5mm][.25mm]{}}%
}
\def\sor@table@headerrow@next{% maybe use llap for the symbol?
\rowfont{\normalfont\bfseries\leavevmode\sor@table@headerstyle}%
\rowcolor{NextHeaderColor}\@ifstar{}{\Gape[.5mm][.25mm]{}}{%
\hspace*{-6mm}%
\llap{\textcolor{NextHeaderColor!40!white}{$\blacktriangledown$}}%
}\hspace*{6mm}$\;$%
}
\else
\def\sor@table@headerrow{\bfseries\@ifstar{}{}}
\def\sor@table@headerrow@next{\bfseries\@ifstar{}{}} % maybe use llap for the symbol?
\fi
% make the basic tets! think about the naming references and mabe make it possible to change the actual name in the settings
% also: allow to add more fields and to give them names
% further: allow them to be ordered
% think about the tokens
% Helper Functions
% i don't want to use collectcell for that, so:
\def\sor@requirement@leftcolstyle#1{\footnotesize\MakeUppercase{#1}}
\def\sor@deflinker#1#2{\expandafter\gdef\csname#1\endcsname{#2}}
% #1: \@sor@currequirementprefix #2: \@sor@r@id #3: \@sor@r@title #4: nmsc pref #5: cont nmsc
\def\sor@write@@linkpos#1#2#3#4#5{
\@ifundefined{@sor@r@titles@#4#5}{%
\expandafter\xdef\csname @sor@r@titles@#4#5\endcsname{#1#2: '#3'}
}{}
\protected@write\@auxout{\let\deflinker\relax}{\protect\sor@deflinker{@sor@r@titles@#4#5}{#1#2: '#3'}}
}
% #1: check for given if not forced
% #2:
\long\def\sor@showifgivenorforced#1#2{%
\ifsor@showall@#2\else\expandafter\ifx\expandafter!#1!\else#2\fi\fi
}
% \ifcase#1 Unwichtig\or Niedrig\or Nett\or Neutral\or Wichtig\or Elementar\else Nicht angegeben\fi
% \colorlet{sor@color@star}{HeaderColor}
\def\sor@setpriority#1{\begingroup\ifnum#1<0\else\color{HeaderColor}\foreach \i in {1,...,5}{\ifnum\i>1\relax \thinspace\fi\ifnum\i>#1\relax \relax \faStarO\else\faStar\fi}\fi\endgroup}
\let\sorSetPriority\sor@setpriority
% Create the basic environments to filter for requirementstype :D
% #1 will initialize the functional@requirement:counter
% #2 should be 'functional' or 'quality' to determine type
\newenvironment{requirements}[2][-1]{%
\def\@sor@tmp@a{#2}% keep to compare
\ifx\@sor@tmp@a\@sor@fnctl\else\ifx\@sor@tmp@a\@sor@qltl\else
\PackageError{sopra-requirements}{requirements second argument MUST be '\@sor@fnctl' or '\@sor@qltl', not '#2'}%
\fi\fi
% only set counter if valid:
\ifnum#1<0\else\setcounter{sor@counter@#2@requirement}{#1}\fi
% every requirement will be set by its own table
% we want to store the curent tableprefix
\expandafter\global\expandafter\let\expandafter\@sor@currequirementprefix\csname sor@#2@requirementprefix\endcsname%
% #1: allows to set a specific counter, otherwise default will be used
% #2: is the title, and has to be given to create a little structure :D
% it is possible to overwrite this title. #2 will always be used for linkage
\NewEnviron{requirement}[2][-1]{%
\stepcounter{sor@counter@#2@requirement}%
\ifnum##1<0\def\@sor@r@id{\@nameuse{thesor@counter@#2@requirement}}%
\else\def\@sor@r@id{##1}\fi%
\def\@sor@r@title{##2}%
\gdef\@sor@r@title{##2}
\def\@sor@r@description{}%
\def\@sor@r@priority{-1}%
\def\@sor@r@justification{}\def\@sor@r@dependencies{}%
\long\def\setDescription####1{\long\gdef\@sor@r@description{####1}}%
\long\def\setPriority####1{\long\gdef\@sor@r@priority{####1}}%
\long\def\setJustification####1{\long\gdef\@sor@r@justification{####1}}%
\def\setDependencies####1{\gdef\@sor@r@dependencies{####1}}%
\def\setTitle####1{\gdef\@sor@r@title{####1}}%
%
\ignorespaces\BODY{}% typeset table:
% Store the Title for the link :D -> we won't use newlabel structure
\sor@write@@linkpos{\@sor@currequirementprefix}{\@sor@r@id}{\@sor@r@title}{\@sor@currequirementprefix}{\@sor@r@id}
\sor@write@@linkpos{\@sor@currequirementprefix}{\@sor@r@id}{\@sor@r@title}{}{##2} % maybe make parseable?
%
% create the label :D
\phantomsection\label{tbl:requirement:\@sor@currequirementprefix\@sor@r@id}%
\label{tbl:requirement:##2}
% for the table of contents (pdf-viewer)
\ifsor@intoc@\addcontentsline{toc}{subsubsection}{\@sor@currequirementprefix\@sor@r@id:\space\@sor@r@title}\else%
\pdfbookmark[4]{\@sor@currequirementprefix\@sor@r@id:\space\@sor@r@title}{sor@shead@@bg@\@sor@currequirementprefix\@sor@r@id}%
\fi
% do not use \Gape for spacing :D
% Now, we're constructing the longtabu
\ifsor@usetabu@%
\taburowcolors[1] 2{lightgray!5 .. lightgray!25}
\everyrow{\tabucline[.4mm white]{}}
\tabulinesep = ^2mm_2mm
\begin{longtabu}{>{~}KV<{~}}
% init the headerrow
\sor@table@headerrow*{ID} & \@sor@currequirementprefix\@sor@r@id\vspace*{-0.1\baselineskip}\ifsor@showtag@\hfill\texttt{##2}\fi\\\endfirsthead
\sor@table@headerrow@next{ID} & \@sor@currequirementprefix\@sor@r@id\vspace*{-0.1\baselineskip}\\\endhead
% i do not want to make a token iter, i'm sorry
\sor@requirement@leftcolstyle{Titel:} & \@sor@r@title \hfill\sor@setpriority{\@sor@r@priority}\\
% only typeset them if they are not empty :D
\sor@showifgivenorforced{\@sor@r@description}{\sor@requirement@leftcolstyle{Beschreibung:} & \@sor@r@description \\}
\sor@showifgivenorforced{\@sor@r@justification}{\sor@requirement@leftcolstyle{Begründung:} & \@sor@r@justification \\}
\sor@showifgivenorforced{\@sor@r@dependencies}{\sor@requirement@leftcolstyle{Abhängigkeiten:} & \foreach[count=\i] \@sor@dpc in \@sor@r@dependencies{%
\ifnum\i>1\relax, \fi% correct comma
\preqref*{\@sor@dpc}%
}}%
\end{longtabu}%
\else\begingroup\renewcommand{\arraystretch}{1.25}
\begin{longtable}{>{~}KV<{~}}
% init the headerrow
\toprule
\sor@table@headerrow* ID & \@sor@currequirementprefix\@sor@r@id\vspace*{-0.1\baselineskip}\ifsor@showtag@\hfill\texttt{##2}\fi\\\midrule\endfirsthead
\sor@table@headerrow@next ID & \@sor@currequirementprefix\@sor@r@id\vspace*{-0.1\baselineskip}\\\midrule\endhead
% i do not want to make a token iter, i'm sorry
\sor@requirement@leftcolstyle{Titel:} & \@sor@r@title \hfill\sor@setpriority{\@sor@r@priority}\\
% only typeset them if they are not empty :D
\sor@showifgivenorforced{\@sor@r@description}{\sor@requirement@leftcolstyle{Beschreibung:} & \@sor@r@description \\}
\sor@showifgivenorforced{\@sor@r@justification}{\sor@requirement@leftcolstyle{Begründung:} & \@sor@r@justification \\}
\sor@showifgivenorforced{\@sor@r@dependencies}{\sor@requirement@leftcolstyle{Abhängigkeiten:} & \foreach[count=\i] \@sor@dpc in \@sor@r@dependencies{%
\ifnum\i>1\relax, \fi% correct comma
\preqref*{\@sor@dpc}%
}\\}%
\bottomrule
\end{longtable}\endgroup\fi\smallskip
}%
}%
% The additional User-Functions :D
% Note: I've written them before, sloppy, for own use - there is no need to
% change that so he following commands will have some funny schduff
\def\sor@thesorversion#1#2#3#4\@nil{{v#1.#2.#3#4}}
\edef\sor@version@str{\noexpand\sor@thesorversion\arabic{sorversion}\noexpand\@nil}
\edef\thesorversion{\sor@version@str}
% we want to automate the requirement structure,
% Please not that, preqref can be used by number AND by ID whereas the ID shouldl never be a number
\DeclareRobustCommand*\preqref{\@ifstar{\@sor@starred@preqref}{\@sor@unstarred@preqref}}
% This one will set the Name too :D
\newcommand\@sor@unstarred@preqref[2][]{\ifx!#1!\pref{tbl:requirement:#2}{\@nameuse{@sor@r@titles@#2}}\else\sor@cstpreqref{#2}{#1}\fi}
\newcommand\@sor@starred@preqref[2][]{\ifx!#1!\pref{tbl:requirement:#2}{#2}\else\sor@cstpreqref{#2}{#1}\fi}
\newlength\sor@ctheight@
\DeclareRobustCommand*\sor@textsuperscript[1]{%
\@sor@textsuperscript{\selectfont#1}}
\def\@sor@textsuperscript#1{%
\settoheight\sor@ctheight@{\fontsize\f@size\z@ A}%
{\m@th\ensuremath{\raise.275\sor@ctheight@\hbox{\fontsize\sf@size\z@#1}}}}
\def\pref#1#2{\hyperref[#1]{#2\sor@textsuperscript{$\,\to p.$\thinspace\pageref{#1}}}}
\def\iskip{\vspace*{\sor@length@list@compensation}}
\def\sor@splittag#1:#2\@nil{#1}
\def\sor@getreqnum#1{\protected@edef\@tmp{\noexpand\sor@splittag\@nameuse{@sor@r@titles@#1}: \noexpand\@nil}\@tmp}
\def\sor@cstpreqref#1#2{\pref{tbl:requirement:#1}{#2 (\sor@getreqnum{#1})}}
\endinput