2

Consider this MWE:

\documentclass{scrartcl}

\usepackage{expl3}

\ExplSyntaxOn

\str_new:N \my_str \str_set:Nn \my_str {Test}

\cs_new:Nn \my_printer:x { \sys_shell_now:n { echo ~ #1 ~ > ~ output } }

% \my_printer:n {This ~ is ~ a ~ test}

\my_printer:n {\my_str ~ another ~ word}

\begin{document} MWE \end{document}

\ExplSyntaxOff

Even though I always added an explicit (non-ignored) space between the words for the argument of \my_printer:n, the second case writes Got 'Testanother word' rather than Got 'Test another word' to the output file. In the example without the macro in the argument, everything works as expected.

If I encountered macros eating spaces in regular LaTeX, I would simply add {} to the end of the macro, ensuring it does not eat the following space as its argument. However, when attempting that within expl3 the braces are actually printed as plain characters.

I also tried explicitly using \use_str:N to get the string's value, but the result is the same.

What is the necessary trick to prevent \my_str from eating up the following spaces?

EDIT:

It turned out that the regular \my_str{} approach works fine for my MWE, but it doesn't work in non-typesetting contexts as e.g. shell-escape (in which case the behavior is as I described it).

EDIT2:

Adapted MWE to actually reflect my problem

Raven
  • 3,023
  • \c_space_str, or a brace group as you would use normally too. – Ulrike Fischer Oct 21 '22 at 14:40
  • \c_space_str doesn't seem to exist. But \c_space_tl does the trick. With brace-group you mean {\my_str} ...? If so, this appeared to have the same issue as \my_str{}: The braces are printed verbatim. – Raven Oct 21 '22 at 14:43
  • 1
    yes sorry, I meant tl and \my_str{} works fine in your example. Btw: you should follow the naming convention of expl3. Your variable e.g. should be called \l_raven_my_str – Ulrike Fischer Oct 21 '22 at 14:46
  • Ah indeed, it does. Then the \my_str{} variant jsut didn't work in my actual use-case, but in my MWE it did work. In my actual example, I am passing the argument to \sys_shell_now:n and apparently somewhere along that way the rules appear to change... With regards to the naming scheme: Yes I do that in my actual code. I only omitted it in my MWE for brevity. – Raven Oct 21 '22 at 14:49
  • 1
    In \ExplSyntaxOn a ~ is the same as a space would otherwise be, and just like the normal rules for spaces, they are ignored after control words by TeX. A ~ there is not the same non-breakable explicit space it would be inside your document. – Skillmon Oct 21 '22 at 14:49
  • 1
    @Raven {} are not printed verbatim here (although thy would be if you put them in a str which is for detokenized strings as for \string where all tokens are catcode 12 or 10 – David Carlisle Oct 21 '22 at 14:50
  • Also "I only omitted it in my MWE for brevity", it's 2022, I think we all can afford the six extra-bytes :P – Skillmon Oct 21 '22 at 14:50
  • @Skillmon fair enough :D – Raven Oct 21 '22 at 15:02
  • Seems like an XY-question. – egreg Oct 21 '22 at 17:36
  • I fixed my MWE to actually reflect my problem. This should not invalidate the accepted answer, though. – Raven Oct 23 '22 at 15:04

2 Answers2

6

The situation is exactly the same as \foo word in classic TeX.

You can use \foo{} word or \foo\space word (or \foo\c_space_tl word)

Note in the first form the {} are not absorbed, they make two additional tokens. An empty group has no effect if typetting but these tokens would show up in a \typeout or shell escape, or other non-typesetting contexts.

David Carlisle
  • 757,742
0

I like to add \xspace from package xspace for all my macro, that take care of typography. For example :

\newcommand{\arduino}{Arduino\textsuperscript{\tiny\textregistered}\xspace}

Note \xspace at the end

Lafée
  • 108
  • I wouldn't recommend \xspace (it just makes your output unreliable), just use correct input. Also \xspace wouldn't help OP in the scenario he's facing at all. – Skillmon Oct 21 '22 at 16:03
  • In general see https://tex.stackexchange.com/questions/86565/drawbacks-of-xspace/86620#86620 but in this case in a \write where {} are writing as themselves \xspace will not work at all as it does not work by expansion. – David Carlisle Oct 21 '22 at 20:02