There are other similar questions, but none that treats explicitly this problem, as far as I can see.
\documentclass{article}
\makeatletter
\newcommand{\generate}[4]{%
%#1 = prefix, #2 = macro, #3 = starting point, #4 = end point
\def\@tempa{#1} % we don't want to lowercase it
\count@=`#3
\loop
\begingroup\lccode`?=\count@
\lowercase{\endgroup\@namedef{\@tempa ?}{#2{?}}}%
\ifnum\count@<`#4
\advance\count@\@ne
\repeat
}
\generate{rv}{\mathbf}{A}{Z}
\show\rvA
\show\rvZ
\generate{rv}{\mathbf}{a}{z}
\show\rva
\show\rvz
The \show
command are just to see that it worked. The terminal output is
> \rvA=macro:
->\mathbf {A}.
l.17 \show\rvA
?
> \rvZ=macro:
->\mathbf {Z}.
l.18 \show\rvZ
?
> \rva=macro:
->\mathbf {a}.
l.20 \show\rva
?
> \rvb=macro:
->\mathbf {b}.
l.21 \show\rvb
An extended version using expl3
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\generate}{ m m m m }
{
\iliketocode_generate:nnnn { #1 } { #2 } { #3 } { #4 }
}
\cs_new_protected:Nn \iliketocode_generate:nnnn
{
\cs_set:Nn \__iliketocode_generate_name:n { #3 }
\cs_set:Nn \__iliketocode_generate_wrapper:n { \exp_not:n { #4 } }
\int_step_inline:nnnn { `#1 } { 1 } { `#2 }
{
\cs_new:cpx
{
\__iliketocode_generate_name:n { \char_generate:nn { ##1 } { 11 } }
}
{
\exp_args:Nf \__iliketocode_generate_wrapper:n { \char_generate:nn { ##1 } { 11 } }
}
}
}
\ExplSyntaxOff
\generate{A}{Z}{rv#1}{\mathbf{#1}}
\show\rvA
\show\rvZ
\generate{a}{z}{rv#1}{\mathbf{#1}}
\show\rva
\show\rvz
\generate{A}{Z}{#1cal}{\mathcal{#1}}
\show\Acal
\show\Zcal
\generate{A}{Z}{#1#1#1}{\mathrm{#1}}
\show\RRR
\show\PPP
The syntax of \generate
is a bit different: the first argument is the starting point, the second argument is the end point; the third argument is the format for the name and the fourth argument is the format for the required definition, where #1
stands for the current letter in the cycle.
The examples should make their meanings clear.
Here's the output on the terminal, just for checking.
> \rvA=\long macro:
->\mathbf {A}.
> \rvZ=\long macro:
->\mathbf {Z}.
> \rva=\long macro:
->\mathbf {a}.
> \rvz=\long macro:
->\mathbf {z}.
> \Acal=\long macro:
->\mathcal {A}.
> \Zcal=\long macro:
->\mathcal {Z}.
> \RRR=\long macro:
->\mathrm {R}.
> \PPP=\long macro:
->\mathrm {P}.
As percusse and cmhughes have pointed out already in their comments, one can try to accomplish your needs with the pgfplotstable
package. Here some code for a starting point, which I think works quite well for vertical tables, but lack for horizontal tables. Although the solution isn't perfect, it hopefully is a good starting point to experiment with.
Please note, that you the key samples at
cannot be used with \addplot gnuplot
. This always uses domain
and samples
to produce the values.
\documentclass[
ngerman,
english, % <-- comment me to use German language
DIV=12,
]{scrartcl}
\usepackage{babel}
\usepackage{caption}
\usepackage{booktabs}
\usepackage{siunitx}
\sisetup{
% just to show where the `\num' command is used
color=green,
}
% this adds the German and UK number format styles to the `siunitx'
% as well as to the tikz/pgf settings and uses them according to
% the actual active language
\addto\extrasngerman{\sisetup{locale = DE}\SendSettingsToPgf}
\addto\extrasenglish{\sisetup{locale = UK}\SendSettingsToPgf}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
% define maximum number of entries in the table
\def\MaxItems{13}
% define which samples should be used (in the plot and table)
\def\Samples{1,1.5,2,3,...,10}
% define stuff that should be used all over the document
\pgfplotstableset{
% to show when there are defined too much cells
empty cells with={NaN},
% -----
% define how the `new' column shall be filled:
create on use/x/.style={
% % unfortunately using `\Samples' here causes an error;
% % don't know why
% create col/set list=\Samples
% so the list entries have to be given here explicitly
create col/set list={1,1.5,2,3,...,10}
},
% create columns that uses the function you need the values for
create on use/x square/.style={
% this fills cells with `0' (zero), when `\MaxItems' is
% larger than the `set list' (or `\Samples')
create col/expr={\thisrow{x}^2}
},
create on use/minus x cube/.style={
create col/expr={-1*\thisrow{x}^3}
},
% -----
% define headers for the corresponding columns
columns/x/.style={
column name=$x$,
dec sep align,
},
columns/x square/.style={
column name=$x^2$,
},
columns/minus x cube/.style={
column name=$-x^3$,
dec sep align,
},
% ----------------------
% I cannot find the following key in the manual
% it doesn't cause an error but also does not do anything
% --> is it intended that one isn't able to set a style for all columns
% or am I missing something in the manual that this can be done?
every column/.append style={
dec sep align,
},
% ----------------------
% % if only vertical tables would be used,
% % one could fix the column name
% every first column/.style={
% column name=$x$,
% },
% -----
% use booktabs to make tables look nicer
every head row/.style={
before row=\toprule,
after row=\midrule,
},
every last row/.style={
after row=\bottomrule,
},
}
% create a new table with `\MaxItem' rows and column 'new':
\pgfplotstablenew[
columns={
x,
x square
},
]{\MaxItems}{\loadedtable}
% % ---------------------------------
% % save table to disc, if you want
% \pgfplotstablesave[
% columns={
% x,
% x square
% },
% ]{\loadedtable}{table-out.txt}
% % ---------------------------------
\sisetup{zero-decimal-to-integer}
\def\pf(#1){\pgfmathparse{\f(#1)}\num{\pgfmathresult}}
\def\f(#1){#1^2} %%It should also be possible to use gnuplots x**2 syntax for the value table
\begin{document}
\section{Create plot}
\begin{center}
\begin{tikzpicture}
\begin{axis}[
domain=-2:10,
]
% define the function to plot
% (it can also be included directly to the argument after
% `expression'. It is only defined here so you don't have to
% change it at several places when the function changes.)
\def\Function{x^2}
% plot the (continuous) function
% (in the `domain' with `samples')
\addplot+ [no markers]
expression {\Function};
% plot points at `samples at'
\addplot+ [mark=x,samples at=\Samples]
expression {\Function};
% plot points from table
% (the points were stated at `set list')
\addplot+ [mark=o]
table {\loadedtable};
% % you can also plot the points from saved table.
% \addplot+ [mark=o]
% table {table-out.txt};
\end{axis}
\end{tikzpicture}
\end{center}
\section{Create tables ``automatically''}
Then I want a value table, something like generated automatically.
\begin{center}
\captionof{table}{Original manual vertical table (\emph{left}) and new
``automatic'' table (\emph{right})}
%% \gen_value_table[samples at={1,2,3.5,10},orientation=]{\f}
\begin{tabular}{c|c}
$x$ & $f(x)$ \\\hline
1 & \pf(1) \\
2 & \pf(2) \\
3,5 & \pf(3.5) \\
10 & \pf(10) \\
\end{tabular}
%
% show (``automatic'') table
\pgfplotstabletypeset{\loadedtable}
%
\pgfplotstabletypeset[
columns={
x,
x square
},
]{
x
1
2
3.5
10
}
\end{center}
\begin{center}
\captionof{table}{Original manual horizontal table (\emph{top}) and new
``automatic'' table (\emph{down})}
%% \gen_value_table[samples at={1,...,10},orientation=horizontal]{\f}
\begin{tabular}{*{10}{c|}c}
$x$& 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 \\\hline
$f(x) $ & \pf(1) & \pf(2) & \pf(3) & \pf(4) & \pf(5) & \pf(6) &\pf(7) & \pf(8) & \pf(9) & \pf(10)
\end{tabular}
\vspace{2ex}
% -----
% up to here everything is fine, but when transposing the table an
% additional header row is created (--> don't know how it can be suppressed).
% Also I don't know why the ``LaTeX'' column headers get lost and only the
% column header from the table is printed
\pgfplotstabletranspose{\loadedtableTransposed}{\loadedtable}
\pgfplotstabletypeset[
every first column/.append style={
string type,
},
input colnames to=,
]{\loadedtableTransposed}
\end{center}
\end{document}
Best Answer
You can use
expl3
's property lists to store the data for you, and then loop through the items in the property list to lay the table out.I defined a command
\DeclareImpact{<label>}{<impact>}{<countermeasure>}
, which replaces your\newcommand{\Impact<label>}{<impact>}
and\newcommand{\Countermeasure<label>}{<countermeasure>}
.After a
<label>
is defined with that you can use\impact{<label>}
and\countermeasure{<label>}
to retrieve the stored texts. If the<label>
was never defined, then a fallback text (defaultNot applicable
) is returned.I also defined a
\TableBody{<list-of-labels>}
command which takes a<list-of-labels>
and typesets the table body based on a template given to\SetRowFormat
(the argument of\SetRowFormat
is used once for each<label>
in the<list-of-labels>
).