6

I am trying to define a message that includes a computed number.

\RequirePackage{expl3}
\ExplSyntaxOn

\int_set:Nn \l_tmpa_int { 42 }
\msg_new:nnn { package } { message } {
  The~number~ \int_use:N \l_tmpa_int ~is~too~large
}
\msg_error:nn { package } { message }

This results in

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! package error: "message"
! 
! The number 42is too large
! 
! See the package documentation for further information.
! 
! Type <return> to continue.
!...............................................  

Note the missing space after the number. To insert it I could

  • make the number an argument, passed when the message is issued. This would take care of the problem in messages, but I suppose it to affect all output material.
  • Replacing the space after the number with \c_space_tl also works. But this does not look like something \c_space_tl was intended for. Is it even save to use \c_space_tl or does it have to be wrapped in \tl_use:N?

Is there a better or even recommended way to insert a space after such a LaTeX3 command?

  • Why isn't \c_space_tl good enough? You can also use \space... – Werner Sep 23 '15 at 23:24
  • @Werner Is \c_space_tl just a \space clone or does it do fancy stuff besides that? – 1010011010 Sep 23 '15 at 23:31
  • @Werner \space is not LaTeX3 and looks quite out of place. \c_space_tl is from the context of token lists, so I wonder if it is semantically fit here. If the answer is yes, this should be the accepted answer to this question and I have a follow-up: Does it have to be wrapped in \tl_use:N? – XZS Sep 23 '15 at 23:33
  • @1010011010 Yes, \c_space_tl is exactly the same as \space. – egreg Sep 24 '15 at 7:26
  • 1
    @egreg: in a message, "backslash space" (no idea how to put that in a comment) also produces a space, and is the preferred approach (when ~ is not usable). – Bruno Le Floch Sep 24 '15 at 16:20
5

It appears that the integer control sequence \l_tmpa_int is gobbling the explicit spaces after it.

To prevent that behavior, I do think \c_space_tl is a good option. It's definition from my copy of expl3-code.tex is

\tl_const:Nn \c_space_tl { ~ }

So the token list is just a space character wrapped in a control sequence. After all of the gobbling of the space characters following the control sequence is finished, that ~ is placed into the input stream, and mission accomplished.

The variable \c_space_tl is usable on its own since, to quote the API documentation, "it is possible to use a <tl var> directly without an accessor function." I've never run into a situation where \tl_use:N was required (not to say it never is) and think it may exist mainly to generate the extremely useful variant \tl_use:c.

Another option is to use the counter as the argument to a function that will output the value of the counter. Three that come to mind are

  • \int_use:c{l_tmpa_int}
  • \int_eval:n{\l_tmpa_int}
  • \int_to_arabic:n{\l_tmpa_int}

With the last one being my favorite due to its extremely explicit nature about what it's doing.


Side note: To prevent this in normal text, I'd append an empty group {} at the end of the sequence, but that appears to generate a literal {} in this context, which is no good.

10

The fact that spaces disappear after a control sequence is unfortunate but unavoidable (this is the same as when TeX ignores spaces in a document after a command).

In a message, use \ (a backslash followed by a space) to produce a space. You can of course use \c_space_tl, but that is longer.

So taking your example, you can do:

\RequirePackage{expl3}
\ExplSyntaxOn

\int_set:Nn \l_tmpa_int { 42 }
\msg_new:nnn { package } { message } {
  The~number~ \int_use:N \l_tmpa_int \ is~too~large
}
\msg_error:nn { package } { message }

I would advise however to pass the value of \l_tmpa_int as an argument to the message:

\RequirePackage{expl3}
\ExplSyntaxOn

\int_set:Nn \l_tmpa_int { 42 }
\msg_new:nnn { package } { message } {
  The~number~#1~is~too~large
}
\msg_error:nnx { package } { message } { \int_use:N \l_tmpa_int }

This way there is no worry about spaces, and if some day you want to provide different choices of languages for your error message that will let you separate a bit better the message text from the implementation detail of using \l_tmpa_int.

  • @TroyHaskin is probably right to advise \int_to_arabic:n, so the best would probably be to use my second proposal (\int_use:N\l_tmpa_int at point of use of the message), but with \int_to_arabic:n{#1} in the message's text. – Bruno Le Floch Sep 24 '15 at 16:18
  • By the way, ~ is active anyway, so why isn't it let to \ within \ExplSyntaxOn? This way it wouldn't be gobbled by any control sequence. – Henri Menke Sep 27 '15 at 15:28
  • @HenriMenke ~ is not active in \ExplSyntaxOn. It has catcode 10. TeX treats any such character as a space. Making ~ active would not do the right thing as the token ~ would end up in definitions, and the value used for it would be the one it has when the code is run, typically in \ExplSyntaxOff context. – Bruno Le Floch Sep 29 '15 at 15:21

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.