1

I'm trying to pass a value of a command to another function without luck. For example I've some data in \DTLloaddb[noheader, keys={key,value}]{definitions}{\data.def} to which I access with \DTLfetch{definitions}{key}{MyFromDate}{value}.

Now I want to pass this value from data.def (e.g 1990-10-09) to \printdate{} so I can format this date into my language preferred format: October 9, 1990.

I thought I could easily pass my returned value which is stored in \DTLfetch{} to \printdate{} without success: \printdate{\DTLfetch{definitions}{key}{MyFromDate}{value}} will throw an error like: ! Illegal parameter number in definition of \iso@date. but calling \DTLfetch{definitions}{key}{MyFromDate} alone will print the unformatted (raw) date value without any problem.

Unfortunately I could not find any help resources concerning passing function values into another function. I would be happy if anybody could provide me some addition information about this topic. Thanks!

2
  • 1
    Welcome to TeX.SX! Please help us help you and add a minimal working example (MWE) that illustrates your problem. Reproducing the problem and finding out what the issue is will be much easier when we see compilable code, starting with \documentclass{...} and ending with \end{document}. Jan 30, 2017 at 21:11
  • Welcome to TeX.SE! Please take a moment to take our Tour!
    – Tavrock
    Jan 31, 2017 at 17:08

1 Answer 1

3

A minimal (non) working example exhibiting what packages/documentclass you use and in which ways macros are called is missing.

I assume \DTLfetch comes from the datatool package and \printdate comes from the isodate package.


On the one hand the command \DTLfetch itself is not a command which is fully expandable. That means that (temporary) assignments and the like get carried out whenever that command is called.

On the other hand \printdate expects its argument to contain only tokens that

  • either are fully expandable and whose expansion at some stage yields only tokens belonging to the character sequence forming the date
  • or belong to the character sequence forming the date.

But the command \DTLfetch does not just print/return a value, it also saves that value to the macro \dtlcurrentvalue.
\dtlcurrentvalue in turn is fully expandable.

Therefore right after calling \DTLfetch you can use the macro \dtlcurrentvalue within the argument of \printdate.

As just said, \DTLfetch does also print the returned value.

If you don't wish the value to be printed, don't use the command \DTLfetch but use the command \DTLgetvalueforkey instead which—within another argument—lets you specify the name of a macro which is to be (re)defined to expand to the desired return-value.

\documentclass[english]{article}
\usepackage{datatool}
\usepackage[num]{isodate}
\usepackage{filecontents}

\begin{filecontents*}{MyDataFile.def}
WhatsoeverKeyA,WhatsoeverValueA
WhatsoeverKeyB,WhatsoeverValueB
MyFromDate,1990-10-09
WhatsoeverKeyC,WhatsoeverValueC
\end{filecontents*}


\newcommand\data{MyDataFile}
\DTLloaddb[noheader, keys={key,value}]{definitions}{\data.def}

\begin{document}

This does both print the return-value and save the return-value to
\verb|\dtlcurrentvalue|:

\verb|\DTLfetch{definitions}{key}{MyFromDate}{value}|:
\DTLfetch{definitions}{key}{MyFromDate}{value}\\
\begingroup\footnotesize
\verb|% use the database "definitions".|\\
\verb|% use the column whose name is "value".|\\
\verb|% use the row which in the column "key" holds the item "MyFromData".|
\endgroup

\verb|\dtlcurrentvalue| yields: \dtlcurrentvalue

Now you can use \verb|\dtlcurrentvalue| within the argument of 
\verb|\printdate|.

\verb|\printdate{\dtlcurrentvalue}| yields: \printdate{\dtlcurrentvalue}

\hrulefill

This does just save the return-value to the macro \verb|\MyCommand|:


\verb|\DTLgetvalueforkey{\MyCommand}{value}{definitions}{key}{MyFromDate}|\\
\begingroup\footnotesize
\verb|% define the macro "\MyCommand".|\\
\verb|% use the database "definitions".|\\
\verb|% use the column whose name is "value".|\\
\verb|% use the row which in the column "key" holds the item "MyFromData".|
\endgroup

\DTLgetvalueforkey{\MyCommand}{value}{definitions}{key}{MyFromDate}        

\verb|\MyCommand| yields: \MyCommand

Now you can use \verb|\MyCommand| within the argument of
\verb|\printdate|.

\verb|\printdate{\MyCommand}| yields: \printdate{\MyCommand}

\end{document}

enter image description here


You wish to have the date formatted as:
<name of the month><non-break-space><day>,<space><year>.

I did not find a way of accomplishing this easily using the isodate package.
Therefore I suggest not using the isodate package but using the packages datetime2 and datetime2-calc which come from the author who also wrote the datatool package, Dr. Nicola Talbot.

Using these packages you can easily define new date styles according to your likings:

\documentclass[english]{article}
\usepackage{datatool, datetime2, datetime2-calc}
\usepackage{filecontents}

\DTMnewdatestyle{MyDatestyle}{% definitions
  % the \number does remove leading zeros from the "day"-element of the date.
  \renewcommand*{\DTMdisplaydate}[4]{\DTMmonthname{##2}~\number##3, ##1}%
  \renewcommand*{\DTMDisplaydate}{\DTMdisplaydate}%
}

\begin{filecontents*}{MyDataFile.def}
WhatsoeverKeyA,WhatsoeverValueA
WhatsoeverKeyB,WhatsoeverValueB
MyFromDate,1990-10-09
WhatsoeverKeyC,WhatsoeverValueC
\end{filecontents*}

\newcommand\data{MyDataFile}
\DTLloaddb[noheader, keys={key,value}]{definitions}{\data.def}

\begin{document}

A new date-style can be defined using \textbf{datetime2 and datetime2-calc}:
\begin{verbatim}
\DTMnewdatestyle{MyDatestyle}{% definitions
  % the \number does remove leading zeros from the "day"-element of the date.
  \renewcommand*{\DTMdisplaydate}[4]{\DTMmonthname{##2}~\number##3, ##1}%
  \renewcommand*{\DTMDisplaydate}{\DTMdisplaydate}%
}
\end{verbatim}

\hrulefill

This does both print the return-value and save the return-value to
\verb|\dtlcurrentvalue|:

\verb|\DTLfetch{definitions}{key}{MyFromDate}{value}|:
\DTLfetch{definitions}{key}{MyFromDate}{value}\\
\begingroup\footnotesize
\verb|% use the database "definitions".|\\
\verb|% use the column whose name is "value".|\\
\verb|% use the row which in the column "key" holds the item "MyFromData".|
\endgroup

\verb|\dtlcurrentvalue| yields: \dtlcurrentvalue

Now you can use \verb|\dtlcurrentvalue| within the argument of
\verb|\DTMdate| and \verb|\DTMDate|.
\begin{verbatim}
\begingroup
\DTMsetdatestyle{MyDatestyle}
\DTMdate{\dtlcurrentvalue}

\DTMDate{\dtlcurrentvalue}
\endgroup
\end{verbatim}%
yields:

\begingroup
\DTMsetdatestyle{MyDatestyle}
\DTMdate{\dtlcurrentvalue}

\DTMDate{\dtlcurrentvalue}
\endgroup

\hrulefill

This does just save the return-value to the macro \verb|\MyCommand|:

\verb|\DTLgetvalueforkey{\MyCommand}{value}{definitions}{key}{MyFromDate}|\\
\begingroup\footnotesize
\verb|% define the macro "\MyCommand".|\\
\verb|% use the database "definitions".|\\
\verb|% use the column whose name is "value".|\\
\verb|% use the row which in the column "key" holds the item "MyFromData".|
\endgroup

\DTLgetvalueforkey{\MyCommand}{value}{definitions}{key}{MyFromDate}

\verb|\MyCommand| yields: \MyCommand


Now you can use \verb|\MyCommand| within the argument of
\verb|\DTMdate| and \verb|\DTMDate|.
\begin{verbatim}
\begingroup
\DTMsetdatestyle{MyDatestyle}
\DTMdate{\MyCommand}

\DTMDate{\MyCommand}
\endgroup
\end{verbatim}%
yields:

\begingroup
\DTMsetdatestyle{MyDatestyle}
\DTMdate{\MyCommand}

\DTMDate{\MyCommand}
\endgroup

\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.