4

I'm just starting my journey with LaTeX3/expl3, and although fascinated by the great work that the LaTeX3 team is doing, and by the enormous difference it brings about with respect to "classical" (La)TeX programming (to me it's such a nice experience that I'll try to stay within its domains as much as possible), I'm still a bit confused on some points. One of those has to do with the \*DocumentCommand family introduced by the xparse package.

So far I had been using the members of this family embedded in a conventional LaTeX2e setting, just toying around with their rich parameter-setting structure and, some mishaps out of lack of practice aside, had no trouble. But now I'm getting eager at having LaTeX3 in my TeX-based work, and I'm trying to embed expl3 code in commands created resorting to the xparse facilities. This is where my trouble starts. Well, maybe this particular issue is not related at all with xparse but with LaTeX3 Booleans, or expansion, or whatever...

Banter enough. This is a small snippet from a real-life working project (not pretending by any means that what follows is good LaTeX3/expl3 practice):

\documentclass{memoir}

\usepackage{xparse,l3keys2e} 

\ExplSyntaxOn

\cs_generate_variant:Nn \bool_new:N {c}
\cs_generate_variant:Nn \bool_if:NTF {cTF}
\cs_generate_variant:Nn \bool_set_true:N {c}

\tl_const:Nn \c_prefix_tl {g_amod} 
\tl_const:Nn \c_postfix_tl {_bool} 

% Booleans making
\NewDocumentCommand\MakeBool { m }
 { 
    \bool_new:c 
    { \tl_use:N \c_prefix_tl { #1 } \tl_use:N \c_postfix_tl }
 }

% Setting Booleans to True
\NewDocumentCommand\SetTBool { m } 
 {
    \bool_set_true:c
    { \tl_use:N \c_prefix_tl { #1 } \tl_use:N \c_postfix_tl }
 }

% Typing Boolean value
\NewDocumentCommand\ShowValBool { m } 
 { 
    \bool_if:cTF 
    { \tl_use:N \c_prefix_tl { #1 } \tl_use:N \c_postfix_tl } 
    { true } { false }
 }

\MakeBool{columns} % Create a Boolean \g_amod_columns_bool

% l3keys defining and setting
\keys_define:nn { amod }
 {
    columns .bool_set:N = \g_amod_columns_bool
 }

\NewDocumentCommand\DocumentSetup { +m }
 { \keys_set:nn { amod } {#1} }

\AtBeginDocument{%
    \DocumentSetup{ columns = false }
}

\begin{document}
\ShowValBool { columns }% False from l3keys 
\par
\SetTBool { columns }% set to True 
\ShowValBool { columns }% True from above command 
\par % Yes, what comes is ugly enough, but just to check...
\bool_if:cTF% raw expl3 code to check Boolean value. Should return True  
   { g_amod_columns_bool }
   { True } { False }
\end{document}

% And, for a terrible ending...
\ExplSyntaxOff

The problem is that I'm gettting False True False, whereas I would expect False True True. What is going on here? What is it that I'm missing or skipping?

  • 1
    I'll try analyzing the code, but at first sight the { #1 } after \c_prefix_tl should lose the braces. – egreg Aug 23 '13 at 9:59
  • 2
    Hm. your question sounds a bit odd. You get false true true and expect false true true. So where is the problem? Beside this I get the correct result if I remove the braces as suggested by egreg in various place and add the missing underscore in the definition of the prefix \tl_const:Nn \c_prefix_tl {g_amod_} (I found out that the underscore is missing by adding \edef\test{\tl_use:N \c_prefix_tl #1 \tl_use:N \c_postfix_tl } \show\test to the MakeBool command.) – Ulrike Fischer Aug 23 '13 at 10:11
  • 1
    Don't use \c_prefix_tl nor \c_postfix_tl: use explicit prefixes. You're also mixing global and local, which is wrong: if a variable is prefixed g_, it's always to be managed as global. – egreg Aug 23 '13 at 10:21
  • 1
    BTW: the c variants you're creating already exist – cgnieder Aug 23 '13 at 10:31
  • 1
    @Marcos The suffix for a boolean should be _bool, so it doesn't make sense to have a token list for it. Prefixes should also be “unique” for a set of macros, in order to help minimizing conflicts; hence having a variable for them is not good programming, in my opinion. – egreg Aug 23 '13 at 10:33
5

I get the correct result if I remove the braces as suggested by egreg in various places and add the missing underscore in the definition of the prefix:

\tl_const:Nn \c_prefix_tl {g_amod_} 

I found out that the underscore is missing by adding

 \edef\test{\tl_use:N \c_prefix_tl #1 \tl_use:N \c_postfix_tl} 
 \show\test 

in the body of the MakeBool command to see the actual name of the created boolean.

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.