I got this Tex command, as a solution to a different problem and it works. But I have trouble understanding the details of how it works since I'm not that proficient in Latex coding and I want to learn.
%\DTLfetchifnull{<db name>}%
% {<column1 name>}%
% {<column1 value>}%
% {<column2 name>}%
% {<tokens in case <column2-value> is not a null-value>}%
% {<tokens in case <column2-value> is a null-value>}%
% {<tokens in case <column1-value> does not exist>}%
%
% Both with <tokens in case <column2-value> is not a null-value> and with
% <tokens in case <column2-value> is a null-value> the macro
% \dtlcurrentvalue is defined to yield the value of the column whose name
% is <column2 name>.
%
\makeatletter
\@ifundefined{NewDocumentCommand}%
{\newcommand\DTLfetchifnull[7]}%
{\NewDocumentCommand\DTLfetchifnull{mmmmmmm}}%
{%
\begingroup%
\protected@edef\@dtl@dogetrowforvalue{%
\noexpand%
\endgroup
\noexpand\dtlgetrowindex{\noexpand\dtl@rowidx}{#1}{\dtlcolumnindex{#1}{#2}}{#3}%
}\@dtl@dogetrowforvalue%
\ifx \dtl@rowidx\dtlnovalue%
\expandafter\@secondoftwo%
\else%
\expandafter\@firstoftwo%
\fi%
{%
\edtlgetrowforvalue{#1}{\dtlcolumnindex{#1}{#2}}{#3}%
\dtlgetentryfromcurrentrow{\dtlcurrentvalue}{\dtlcolumnindex{#1}{#4}}%
\DTLifnull{\dtlcurrentvalue}{#6}{#5}%
}{%
#7%
}%
}%
\makeatother
- The \makeatletter … \makeatother as I understand is necessary, because we change something fundamental about NewDocumentCommand and newcommand?
- @ifundefined{NewDocumentCommand}% as I understand makes it possible to use NewDocumentCommand instead of newcommand without \usepackage{xparse}?
Why do we need this? Can we just use \usepackage{xparse} and skip the whole:
\makeatletter
\@ifundefined{NewDocumentCommand}%
{\newcommand\DTLfetchifnull[7]}%
...
\makeatother
Or is there an advantage in doing this way?
-
\begingroup … \endgroup as I understand is something likeĀ '{ }' but with different behavior
-
but it enclosed "\protected@edef@dtl@dogetrowforvalue{" so the "}" is outside, how does that work?
\begingroup%
\protected@edef@dtl@dogetrowforvalue{%
\noexpand%
\endgroup
\noexpand\dtlgetrowindex{\noexpand\dtl@rowidx}{#1}{\dtlcolumnindex{#1}{#2}}{#3}%
}@dtl@dogetrowforvalue%
I find it very hard to read how these functions are encapsulated and to decide what is an argument of which function or just following after a function.
This says check if(\dtl@rowidx\dtlnovalue) do \expandafter@secondoftwo else \expandafter@firstoftwo.
\ifx \dtl@rowidx\dtlnovalue
\expandafter\@secondoftwo
\else
\expandafter\@firstoftwo
\fi
Are @firstoftwo and @secondoftwo the two options in curly braces that are coming after this?
Best Answer
\makeatletter
and\makeatother
are needed in order to allow using command names with@
in them. There is nothing really special about it.The first idea is to use
\NewDocumentCommand{\DTLfetchifnull}{mmmmmmm}
if it is available, otherwise the standard\newcommand{\DTLfetchifnull}[7]
is used (for compatibility with older documents).With newer releases we essentially get
that shows not really good programming style. For instance, there are several useless
%
, but they're not harmful, just annoying. Also the first\noexpand
is useless, because `\endgroup is not expandable. I'd write it asIf an older LaTeX release, the first line would be
\newcommand{\DTLfetchifnull}[7]
.The idea is to define
\@dtl@dogetrowforvalue
to yieldand then the scratch macro
\@dtl@dogetrowforvalue
will be executed, which will assign a meaning to\dtl@rowidx
, which can be\dtlnovalue
(depending on the arguments#1
,#2
and#3
. The initial\endgroup
will balance the already digested\begingroup
and the definition of\@dtl@dogetrowforvalue
will be forgotten as soon as\endgroup
is executed (but the expansion of\@dtl@dogetrowforvalue
has already been placed on the input stream, so there is no problem with undefining it).Next the token is compared with
\dtlnovalue
. The constructionis very common in LaTeX programming. If the test returns true,
tokens B
will be used, otherwisetokens A
.So, if
\dtl@rowidx
turns out to be\dtlnovalue
, the argument#7
will be used. Otherwise it will be some legal row index andwill be used. Finding out what this does needs studying the manual of
datatool
.