summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/decision-table/decision-table.sty
blob: 2e1bf385391741cd8d00558f0acf41f1fe45ca53 (plain)
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
% The decision-table package is the easiest way to generate tables in the Decision Model and Notation (DMN) format.
%
%% decision-table.sty
%% Copyright 2020 Simon Vandevelde
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
% 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.3c 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 Simon Vandevelde.
%
% This work consists of the file decision-table.sty
%
%% This package creates the \dmntable command.
%% Requires the following input:
%%   1: table title
%%   2: hit policy
%%   3: input columns, separated by commas (e.g. 'weight, length')
%%   4: output columns, separated by commas (e.g. 'BMI')
%%   5: cell values, separated by commas (e.g. '>80, ---, weight/length*length,
%
%% The package depends on two other packages: 'colortbl' and 'booktabs'.

\ProvidesPackage{decision-table}[2020/08/22 v0.0.2 LaTeX package for DMN]


\RequirePackage{colortbl}  % Color in the cells.
\RequirePackage{booktabs}  % Special header format.


\definecolor{inputgreen}{RGB}{182, 215, 168}
\definecolor{inputblue}{RGB}{207, 226, 243}
\definecolor{glossaryorange}{RGB}{255, 123, 89}
\definecolor{executered}{RGB}{236, 155, 164}
\newcommand{\inputcol}[1]{\cellcolor{inputgreen} \textbf{#1}}
\newcommand{\outputcol}[1]{\cellcolor{inputblue} \textbf{#1}}
\newcommand{\glossarycol}[0]{\cellcolor{glossaryorange}}
\newcommand{\executecol}[0]{\cellcolor{executered}}
\newcommand{\dmnfont}[0]{\fontsize{7}{9} \fontfamily{put} \selectfont \setlength{\belowrulesep}{0pt}}

% Code to iterate over strings separated by comma's and executing a macro on each of them.
\makeatletter

% Functional foreach construct 
% 1 - Function to call on each comma-separated item in param 3
% 2 - Parameter to pass to function in param 1 as first parameter
% 3 - Comma-separated list of items to pass as second parameter to function in param 1
\def\foreach#1#2#3{%
  \@test@foreach{#1}{#2}#3,\@end@token%
}

% Internal helper function - Eats one input
\def\@swallow#1{}

% Internal helper function - Checks the next character after param 1 and param 2 and 
% continues loop iteration if \@end@token is not found 
\def\@test@foreach#1#2{%
  \@ifnextchar\@end@token%
    {\@swallow}%
    {\@foreach{#1}{#2}}%
}

% Internal helper function - Calls 1{2}{3} and recurses
% The magic of splitting the third parameter occurs in the pattern matching of the \def
\def\@foreach#1#2#3,#4\@end@token{%
  #1{#2}{#3}%
  \@test@foreach{#1}{#2}#4\@end@token%
}

%%% Macro's which are used in the above iteration function.
% Formats the inputcol as "\& \inputcol('input')".
\def\makeinputcol#1#2{&\inputcol{#2}}
% Formats the outputcol as "\& \outputcol('output')".
\def\makeoutputcol#1#2{&\outputcol{#2}}

\def\makecol#1#2{  % Format the cells. Needs to add in \\\hline after the right amount of cells.
    \ifnum\colcounter=\nbcols%  If we're at the end of a row, reset the counter and add the \\\hline
        \global\colcounter=0\relax
        \uppercase{\\} \hline \the\rowcounter
        \global\advance\rowcounter by 1
    \else
    \fi%5
    \global\advance\colcounter by 1
    \uppercase{&} {#2}
}

% Increments the counters by one, in order to count inputs or outputs using the above loop function.
\def\countinput#1#2{\global\advance\nbinputs by 1\relax}
\def\countoutput#1#2{\global\advance\nboutputs by 1\relax}

\makeatother

% Command to create a DMN table in a tabular environment.
% Requires the following input:
%   1: table title
%   2: hit policy
%   3: input columns, separated by commas (e.g. 'weight, length')
%   4: output columns, separated by commas (e.g. 'BMI')
%   5: cell values, separated by commas (e.g. '>80, ---, weight/length*length,
%                                               <80, ---, length/weight*weight')
\newcommand{\dmntable}[5]{
    % Create and instantiate counters.
    \newcount{\nbinputs}
    \newcount{\nboutputs}
    \newcount{\nbcols}  % The width of a table.
    \newcount{\colcounter}
    \newcount{\rowcounter}
    \nbinputs=0\relax
    \nboutputs=0\relax
    \nbcols=0\relax
    \colcounter=0\relax
    \rowcounter=2\relax

    \newcount\X
    {
        % Set the correct font.
        \dmnfont

        % Count the amount of inputs and outputs.
        \foreach{\countinput}{}{#3}
        \foreach{\countoutput}{}{#4}
        % Sum them together to find the number of columns of the table.
        \advance\nbcols by \nbinputs
        \advance\nbcols by \nboutputs

        % X is the first index number, always 1.
        \X=1
        \advance\nbinputs by 1\relax  % To make space for the index
        \begin{tabular}{|r|*{\nbcols}{l|}}
            \expandafter\cmidrule{1-\nbinputs}  % Makes sure the top hline is not the full width.
            \multicolumn{\nbinputs}{|l|}{#1} & \multicolumn{\nboutputs}{c}{}\\ % Set the input and output as multicolumn.
            \hline
            #2 \foreach{\makeinputcol}{}{#3} \foreach{\makeoutputcol}{}{#4} \\ % Generate input and outputheaders.
            \hline
            \the\X \foreach{\makecol}{}{#5} \\  % Generate the cell values
            \hline
        \end{tabular}
    }
}

\endinput
%%%
%%% End of file 'dmn.sty'