# key-value is not being read as expected

I'm trying to write some code that allows me to reveal in stages the content of a pre-existing file (a pspicture showing a geometric construction). I'm trying to write this using LaTeX3. I've got some working code, but I don't like how I'm implementing it. Currently, the working version is a hobbled together collection of commands. I want to streamline this using l3keys. However, I'm getting stuck.

What's working:

Here's what I've got that's working. There are three files:

File in which I define the expl3 interface: this is put in a file called stages.tex

%% defining stages
\usepackage{xparse}
\usepackage{verbatim}
\ExplSyntaxOn

\tl_new:N    \ace_reveal_tl
\tl_gset:Nn  \ace_reveal_tl {REVEAL}
\tl_new:N    \ace_conceal_tl
\tl_gset:Nn  \ace_conceal_tl {CONCEAL}

\NewDocumentCommand{\revealstage}{ m }{
\tl_gset:cV { ace__reveal__ #1 __stage__new } \ace_reveal_tl
}
\NewDocumentCommand{\burystage}{ m }{
\tl_gset:cV { ace__reveal__ #1 __stage__new } \ace_conceal_tl
}

\NewDocumentCommand{\testforstage}{ m m m }{
\tl_if_eq:cNTF { ace__reveal__ #1 __stage__new } \ace_reveal_tl
{#2}
{#3}
}

\NewDocumentEnvironment{stage}{ m }
{
\tl_if_eq:cNF { ace__reveal__ #1 __stage__new } \ace_reveal_tl
{\expandafter\comment}
}
{
\tl_if_eq:cNF { ace__reveal__ #1 __stage__new } \ace_reveal_tl
{\expandafter\endcomment}
}

\ExplSyntaxOff


File in which I define the picture I'm using in which I implement stages: this file is called diagram.tex

\begin{pspicture}[showgrid=false](-20,-13)(20,13)
%..% compass directions %..%
{
\psset{PointName=none,PointSymbol=none}
\pstGeonode(0,0){o}(1,0){r}(0,1){u}
\pstRotation[RotAngle=20]{o}{r}[r1]
\pstGeonode(0,0){Q}
}
%% temporarily define midpont of segment(PQ) --> M to control positioning
\pstGeonode[PointName=none,PointSymbol=none,PosAngle=0](0,0){tM}
%% point outside the circle and the center of circle
\pstTranslation[DistCoef=14,PosAngle=80]{o}{r1}{tM}[Q]
\pstTranslation[DistCoef=10,PosAngle=-100]{r1}{o}{tM}[P]
%% construct circle centered at P

%% construct mid-point between P and Q
\pstTranslation[DistCoef=9,PointName=none,PointSymbol=none]{o}{r}{P}[B]
\pstTranslation[DistCoef=0.5,PointName=none,PointSymbol=none]{P}{Q}{P}[M]
%% show constructions
\begin{stage}{midpoint}
\pstLineAB[linecolor=blue,linewidth=0.1pt,linestyle=dashed]{P}{Q}
\pstGeonode[PointName=M,PosAngle=-90](M){showM}
\end{stage}

%% construct circle centered at M passing through P and Q
\begin{stage}{large circle}
\pstCircleOA[linecolor=blue,linewidth=0.2pt,linestyle=dashed]{M}{P}
\end{stage}

%% construct tangents
\begin{stage}{tangents}
\testforstage{large circle}{
\pstGeonode[PointName={U},PosAngle=-90](U){showU}
\pstGeonode[PointName={V},PosAngle=110](V){showV}
}{
\pstGeonode[PointName={U},PosAngle=-50](U){showU}
\pstGeonode[PointName={V},PosAngle=90](V){showV}
}
\pstLineAB[linecolor=red,nodesep=-8]{Q}{V}
\pstLineAB[linecolor=red,nodesep=-8]{Q}{U}
\end{stage}

\end{pspicture}


The main document:

\documentclass{article}
\usepackage{pstricks,pst-eucl}
\psset{unit=0.15cm}
\usepackage[margin=1in]{geometry}
\input{stages}
\pagestyle{empty}
\begin{document}

\input{diagram}

\revealstage{midpoint}
\input{diagram}

\revealstage{large circle}
\input{diagram}

\revealstage{tangents}
\input{diagram}

\burystage{midpoint}
\burystage{large circle}
\input{diagram}

\end{document}


This creates:

What's not working:

I would really like to be able to write something like the following lines in the main document:

\activatestage[reveal=midpoint,
conceal={large circle,
midpoint}]
{diagram}


But this above example is a bit more sophisticated than I've currently tried to implement. Currently, I haven't written code to handle passing multiple values to be parse by the key. I've only written something that I believe should be able to handle the following:

\activatestage[reveal=midpoint,
conceal=large circle]
{diagram}


And this is the code I use to try to implement this:

%% defining keys
\ExplSyntaxOn
\keys_define:nn { stages }{
reveal  .code:n = \fnc_reveal_stages:n #1,
conceal .code:n = \fnc_conceal_stages:n #1
}

\cs_new:Npn \fnc_reveal_stages:n #1 {
\tl_gset:cV { ace__reveal__ #1 __stage__new } \ace_reveal_tl
}

\cs_new:Npn \fnc_conceal_stages:n #1 {
\tl_gset:cV { ace__reveal__ #1 __stage__new } \ace_conceal_tl
}

\NewDocumentCommand{\activatestage}{ o m }{
\tl_set:Nn  \l__no_value_tl         { \NoValue    }
\tl_set:Nn  \l__keys_present_tl     { #1 }
\tl_show:N \l__keys_present_tl
\bool_if:nF {        \tl_if_eq_p:NN \l__keys_present_tl  \l__no_value_tl) }
{
\keys_set:nn{ stages }{#1}
}
\input{#2}
}
\ExplSyntaxOff


I've put the above in its own file called additions.tex

Here's the main document where I try to implement the new approach:

\documentclass{article}
\usepackage{pstricks,pst-eucl}
\psset{unit=0.15cm}
\usepackage[margin=1in]{geometry}
\input{stages}
\pagestyle{empty}
\begin{document}

\input{diagram}

\revealstage{midpoint}
\input{diagram}

\revealstage{large circle}
\input{diagram}

\revealstage{tangents}
\input{diagram}

\activatestage[reveal=midpoint,
conceal=large circle]
{diagram}

\end{document}


But this results in:

But this isn't doing what I expect (as you can see by comparing to my working example). The key seems to only see the first letter of the value being passed to it. How do I get the key to see the entire value?

-
At least it should be reveal .code:n = \fnc_reveal_stages:n {#1} Always put braces around an n-type argument. –  egreg Jan 26 '13 at 18:10
@egreg. Oh how humiliating! Such a simple mistake. Thank you! –  A.Ellett Jan 26 '13 at 18:12
You should use a boolean, instead of comparing token lists for concealing or revealing the environment. –  egreg Jan 26 '13 at 18:13
@egreg. I'm not sure how to implement that. The reason is that I would like the user to have the freedom to define the names for the blocks to be revealed/concealed. –  A.Ellett Jan 26 '13 at 18:18
You can define "named" conditionals with \bool_new:c, maybe checking first if they are already existent; then you can use \bool_gset_true:c and \bool_gset_false:c for setting them and \bool_if:cTF for using them. –  egreg Jan 26 '13 at 18:22

Enclose n-type arguments in braces: it should be

\keys_define:nn { stages }
{
reveal  .code:n = \fnc_reveal_stages:n  { #1 },
conceal .code:n = \fnc_conceal_stages:n { #1 },
}


Here's a proposal using booleans and a good deal of simplifications. However, you should also add a command for defining all allowed "stages".

\documentclass{article}
\usepackage{pstricks,pst-eucl}
\psset{unit=0.15cm}

\usepackage[margin=1in]{geometry}

%% defining stages
\usepackage{xparse}
\usepackage{verbatim}
\ExplSyntaxOn

\NewDocumentCommand{\revealstage}{ m }
{
\ace_reveal_stage:n { #1 }
}
\cs_new_protected:Npn \ace_reveal_stage:n #1
{
\bool_if_exist:cF { g__ace_reveal_ #1 _stage_bool }
{ \bool_new:c { g__ace_reveal_ #1 _stage_bool } }
\bool_gset_true:c { g__ace_reveal_ #1 _stage_bool }
}
\NewDocumentCommand{\burystage}{ m }
{
\ace_conceal_stage:n { #1 }
}
\cs_new_protected:Npn \ace_conceal_stage:n #1
{
\bool_if_exist:cF { g__ace_reveal_ #1 _stage_bool }
{ \bool_new:c { g__ace_reveal_ #1 _stage_bool } }
\bool_gset_false:c { g__ace_reveal_ #1 _stage_bool }
}

\NewDocumentCommand{\testforstage}{ m m m }
{
\bool_if:cTF { g__ace_reveal_ #1 _stage_bool } { #2 } { #3 }
}

\NewDocumentEnvironment{stage}{ m }
{
\bool_if:cF { g__ace_reveal_ #1 _stage_bool } {\comment}
}
{
\bool_if:cF { g__ace_reveal_ #1 _stage_bool } {\endcomment}
}

%%% Keyval syntax

\keys_define:nn { stages }{
reveal  .code:n = \ace_reveal_stage:n  { #1 },
conceal .code:n = \ace_conceal_stage:n { #1 },
}

\NewDocumentCommand{\activatestage}{ O{} m }
{
\keys_set:nn { stages } { #1 }
\input{#2}
}

\ExplSyntaxOff

\pagestyle{empty}
\begin{document}

\activatestage[reveal=midpoint,
conceal=large circle]
{diagram}

\end{document}


## Notes

1. Comparing token lists is not an efficient way; booleans are surely better.

2. Please, stick to the naming conventions; variables should start with l_ or g_ (or l__ and g__ if they are "internal").

3. \keys_set:nn is perfectly happy to process an empty argument, so

\NewDocumentCommand{\activatestage}{ O{} m }


is much more efficient than your testing of \NoValue. In any case, you should use \IfNoValueTF to test for the presence of an optional argument.

-
Other than the accessor commands, your MWE is pretty much exactly how I rewrote my document after your suggestion to use booleans. Thank you for showing the \bool_if_exist. I've also implemented setting multiple values through \clist_set:Nn \l__ace_stages {#1} and then calling \clist_map_inline:Nn \l__ace_stage { \bool_gset_true:c { g__ace_reveal_ ##1 _stage_new } }. And mutatis mutandis, for the conceal side of things. I have some very nice code now. Thank you again. –  A.Ellett Jan 26 '13 at 19:08