3

How to make \foo_bar: expand to code a?

\bool_new:N \foo_bool
\bool_set_true:N \foo_bool

\cs_new:Nn \foo_bar:
  {
    \bool_if:NTF \foo_bool
      { code~ a } { code~ b }
  }

update:

How about this one?

% `test.pdf` is in the current directory.
\cs_new:Nn \foo_bar:
  {
    \file_if_exist:nTF { test.pdf }
      { code~ a } { code~ b }
  }

(Complete question can be found in Expand condition functions in xeCJK)

  • Could you 'expand' your fragment into a compilable document first, please ;-), but it should be \cs_new_nopar:Nn \foo_bar: rather. But it expands to a for me – user31729 Jul 13 '17 at 17:16
  • Use \cs_new:Nx (or define a variant \cs_new:Nf) – egreg Jul 13 '17 at 17:17
  • Sorry, changing the question and piling up new requests is not the way to react to answers ;- – user31729 Jul 13 '17 at 17:39
  • Sorry for that... But the second one is actually what I need to do and I think both questions are interesting. – stone-zeng Jul 13 '17 at 17:45
  • \file_if_exist:nTF is not expandable. – Bruno Le Floch Jul 13 '17 at 19:02
2

If the conditional value of \foo_bool should be frozen (expanded) in the definition of the macro, \cs_new:Nx is one possibility, if the macro should 'react' on the current value of \foo_bool, use \cs_new:Nn here.

I've changed the names to 'proper' expl3 naming conventions.

\documentclass{book}

\usepackage{xparse}

\ExplSyntaxOn

\bool_new:N \l_stone_foo_bool
\bool_set_false:N \l_stone_foo_bool% Set to false, although false by def. 

\cs_new:Nn \foo_bar_current:
{
  \bool_if:NTF \l_stone_foo_bool
  { code~ a } { code~ b }
}

\cs_new:Nx \foo_bar_expanded:
{
  \bool_if:NTF \l_stone_foo_bool
  { code~ a } { code~ b }
}


\NewDocumentCommand{\foo}{}{%
  \foo_bar_expanded:
}

\NewDocumentCommand{\foobar}{}{%
  \foo_bar_current:
}

\bool_set_true:N \l_stone_foo_bool% For testing
\ExplSyntaxOff
\begin{document}
\foo\ and \foobar

\end{document}

\foo will expand to code b and \foobar will expand to code a, since setting the bool variable to true in the meantime, after defining \foobar.

enter image description here

  • 1
    FYI, we've moved away from encouraging _nopar use for argument-less macros because it adds things to think about with no benefit. In the core expl3 the only _nopar macros are user-facing ones or those that have to be compared to token lists. – Bruno Le Floch Jul 13 '17 at 19:01
  • @BrunoLeFloch: Eh, since which date you're encouraging users away from this? I was scolded two years ago, starting with expl3, for not using _nopar :-( – user31729 Jul 13 '17 at 19:02
  • Sorry, we learn from experience. I have no idea when we changed. – Bruno Le Floch Jul 13 '17 at 19:04
  • @ChristianHupfer As Bruno says, we realised a while ago that other than for setting up xparse and for some limited internal place, using nopar didn't really help. (For document-level interfaces it's different.) So it's not wrong to use nopar, it's just that we wouldn't do it now. As Bruno says, this is the 'experimental' part of expl3: there are changes as new ideas come forward. – Joseph Wright Jul 14 '17 at 5:26
  • @JosephWright: Removed the _nopar 'modifier'... – user31729 Jul 17 '17 at 20:51
1

I guess you are defining a function that depends on some runtime options. The solution is to use \cs_new:Nx (which internally uses \edef).

\documentclass{article}
\usepackage{expl3}

\ExplSyntaxOn

\bool_new:N \l_stonezeng_foo_bool

% true branch
\bool_set_true:N \l_stonezeng_foo_bool

\cs_new:Nx \stonezeng_foo_t:
 {
  \bool_if:NTF \l_stonezeng_foo_bool
   {
    \exp_not:n { code~a }
   }
   {
    \exp_not:n { code~b }
   }
 }

% false branch
\bool_set_false:N \l_stonezeng_foo_bool

\cs_new:Nx \stonezeng_foo_f:
 {
  \bool_if:NTF \l_stonezeng_foo_bool
   {
    \exp_not:n { code~a }
   }
   {
    \exp_not:n { code~b }
   }
 }

\cs_show:N \stonezeng_foo_t:
\cs_show:N \stonezeng_foo_f:

\stop

This will show on the terminal

> \stonezeng_foo_t:=\long macro:->code a.

> \stonezeng_foo_f:=\long macro:->code b.

Note \exp_not:n, so the inner code will not be expanded at definition time, but only upon usage.

Remember to use proper naming of variables and functions.

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.