11

So, I'm trying to pass the "date" value associated with the current environment to a property list defined by a macro. It doesn't seem to work and I'm not sure why. Here's a MWE:

\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn

\tl_new:N \l_thedate_tl

\NewDocumentEnvironment{Day}{m}{
  \tl_set:Nn \l_thedate_tl {#1}
  \begin{center}
    \textbf{#1}
  \end{center}
  Begin:\\
}{
\\
End.
}

\NewDocumentCommand{\writeentry}{mm}{
  \prop_new:c {g_#1_prop}
  \prop_gput:cnn {g_#1_prop} {key} {#1}
  \prop_gput:cnn {g_#1_prop} {value} {#2}
  \prop_gput:cnn {g_#1_prop} {date} {\tl_to_str:N \l_thedate_tl}
  #1 \hspace{2em} #2
}

\NewDocumentCommand{\getdate}{m}{
  \prop_get:cn {g_#1_prop} {date}
}
\NewDocumentCommand{\getvalue}{m}{
  \prop_get:cn {g_#1_prop}{value}
}
\ExplSyntaxOff
\begin{document}

\begin{Day}{14 April}
  \writeentry{foo}{Something}

  \writeentry{bar}{Something else}
\end{Day}

Get Value: \getvalue{foo} \hspace{2em}
Get Date: \getdate{foo}
\end{document}

As you can see, the \getdate function doesn't print anything. But as I understand it, it should print the value that \l_thedate_tl had when the property list was set.

What am I doing wrong?

  • You are storing the literal tokens \tl_to_str:N \l_thedate_tl} in the prop, and at point-of-use \l_thedate_tl is empty: is that what you are missing? – Joseph Wright Apr 14 '14 at 15:11
  • Probably you want \prop_gput:cnV {g_#1_prop} {date} \l_thedate_tl – egreg Apr 14 '14 at 16:01
9

You don't want \tl_to_str:N and most of all you don't want to put \tl_to_str:N \l_thedate_tl into the property list, but the value of the token list variable. So \prop_gput:cnV is your friend:

\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn

\tl_new:N \l_seamus_thedate_tl

\NewDocumentEnvironment{Day}{m}{
  \tl_set:Nn \l_seamus_thedate_tl {#1}
  \begin{center}
    \textbf{#1}
  \end{center}
  Begin:\\
}{
\\
End.
}

\NewDocumentCommand{\writeentry}{mm}{
  \prop_new:c {g_seamus_#1_prop}
  \prop_gput:cnn {g_seamus_#1_prop} {key} {#1}
  \prop_gput:cnn {g_seamus_#1_prop} {value} {#2}
  \prop_gput:cnV {g_seamus_#1_prop} {date} \l_seamus_thedate_tl
  #1 \hspace{2em} #2
}

\NewDocumentCommand{\getdate}{m}{
  \prop_get:cn {g_seamus_#1_prop} {date}
}
\NewDocumentCommand{\getvalue}{m}{
  \prop_get:cn {g_seamus_#1_prop}{value}
}
\ExplSyntaxOff
\begin{document}

\begin{Day}{14 April}
  \writeentry{foo}{Something}

  \writeentry{bar}{Something else}
\end{Day}

Get Value: \getvalue{foo} \hspace{2em}
Get Date: \getdate{foo}
\end{document}

If I also ask \prop_show:N \g_seamus_foo_prop I get

The property list \g_seamus_foo_prop contains the pairs (without outer braces):
>  {key}  =>  {foo}
>  {value}  =>  {Something}
>  {date}  =>  {14 April}.

which seems exactly what you want.

Note the use of a prefix, which is heartily recommended.


A crash course on variants

The main function you're using is \prop_gput:Nnn, but nowhere you type it, but rather a couple of variants thereof.

The kernel has a definition for \prop_gput:Nnn and then it says

\cs_generate_variant:Nn \prop_gput:Nnn { cnn }
\cs_generate_variant:Nn \prop_gput:Nnn { NnV }
\cs_generate_variant:Nn \prop_gput:Nnn { cnV }

(and some other variants). These commands really define three new functions

\prop_gput:cnn
\prop_gput:NnV
\prop_gput:cnV

that are based on the main function, preceded by some \expandafter trickery so that calling

\prop_gput:cnn { g_seamus_foo_prop } { X } { Y }

is equivalent to calling

\prop_gput:Nnn \g_seamus_foo_prop { X } { Y }

that is, a control sequence name is formed from the argument. Of course this is useful only when the control sequence name has a variable part, as in your code.

Calling

\prop_gput:NnV \g_seamus_foo_prop { X } \l_seamus_thedate_tl

is instead equivalent to calling

\prop_gput:Nnn \g_seamus_foo_prop { X } { <value of \l_seamus_thedate_tl> }

So a V argument is substituted with the variable's value in braces. The third function is just a combination of the two variants above.

This provides a unified way of doing things, without multiplying the “base names” of functions: all of them are \prop_gput:<signature>.

  • Thanks. So the V expands the argument? Is that the right way to think about it? – Seamus Apr 15 '14 at 11:15
  • 1
    @Seamus V presents the argument to the function as if it were the variable's value enclosed in braces. – egreg Apr 15 '14 at 11:23
  • Thanks. That's really helpful. I am slowly getting the hang of the LaTeX3 way! – Seamus Apr 15 '14 at 12:02

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.