0

Assume you use xparse and have

\NewDocumentCommand{\macro}{+m}{%
   \addcontentsline{foo}{#1}%
}%

With \macro{some text} you get into the .aux-file something like \@writefile{foo}{some text}.

From time to time I wish to have processed material tokenized under verbatim-catcode-régime in a similar way. I.e.,

\verbmacro|some text
some text
some text|

should (with \newlinechar=\endlinechar and immediate-writing for ensuring that the change of \newlinechar is in effect while writing to the aux-file) in the .aux-file yield something like:

\@writeVerbatimArgFile{foo}|some text
some text
some text|

\@writeVerbatimArgFile could process its second argument as +v-type argument.

The crucial point is:

If you make \verbmacro's argument a +v-type-argument, the surrounding verbatim-delimiter is stripped off. But it is needed because it shall appear in the .aux-file, in the \@writeVerbatimArgFile-entry, also.

Therefore my question is:

Does adding to xparse a v/+v-like argument-type where the verbatim-delimiter does not get removed make sense?

Do people who would use this belong to such a small minority that implementing that in xparse is not worth the efforts?

Please, don't misunderstand me: This is not intended as a "Do-it-for-me!"-question. I already have my own routines (not based on xparse) for doing such things. E.g., the routine \UDcollectverbarg in the second example of my answer to the question "Unique requirement IDs and list of corresponding test method" collects verbatimized arguments both without and with the delimiter.

The question is: Would such an argument type be used often enough that the effort of implementing it and spending memory resources for storing the underlying macro-mechanisms would be worthwhile?


At first glimpse you could think of defining \verbmacro in a way where | is prepended and appended to the +v-type-argument before writing to the .aux-file.

If you did that, you could not do things like

\verbmacro?some text with | in it?

any more.

With a hardcoded | you would get a \@writeVerbatimArgFile-entry like this:

\@writeVerbatimArgFile{foo}|some text with | in it|

This might be a problem.

If the verbatim-delimiter is not hardcoded but passed on, you get:

\@writeVerbatimArgFile{foo}?some text with | in it?

, which should not be a problem...

Ulrich Diez
  • 28,770
  • 1
    It wouldn't be particularly hard to implement this (in fact, the begin marker is stored in the grabbed argument for most part of the xparse-ing process, so probably just a minor tweak), but it would probably make an awkward argument type, mostly because other verbatim-like commands “remove” the delimiter. Why not just write a pair of |...| around the argument? – Phelype Oleinik Nov 30 '19 at 00:09
  • @PhelypeOleinik I added a remark to my question. If you somewhere "hardcode" the verbatim-delimiter instead of passing it on, you are bound to always using the hardcoded verbatim-delimiter... – Ulrich Diez Nov 30 '19 at 00:22
  • 1
    Oh, right, that makes sense. It would be quite easy to patch the v argument to always keep the delimiters (two copies of the first delimiter, actually): \cs_gset_protected:Npn \__xparse_grab_v_aux_loop_end: { \__xparse_grab_v_group_end: \__xparse_add_arg:x { \exp_not:V \l__xparse_v_arg_tl \tl_head:N \l__xparse_v_arg_tl } }. To have it be a new argument type you'd probably need to copy the entire definition of the v type argument and change that bit. – Phelype Oleinik Nov 30 '19 at 00:37
  • I'm not yet - I intend to become. ;-) - familiar enough with expl3-syntax and xparse's internals for seeing it myself immediately: Does this take into account the case of the verbatim-arg being wrapped in { and } (which is possible with v/+v-arguments)? In this case first and second delimiter differ, thus in this case the phrase "two copies of the first delimiter" might not describe the situation correctly... – Ulrich Diez Nov 30 '19 at 00:45
  • 1
    No, that's exactly it, two copies of the first delimiter. For a v-type argument, xparse will grab it token by token, and store that in the \l__xparse_v_arg_tl token list along with the first delimiter so, say, \test|hello| would end up as |hello in \l__xparse_v_arg_tl at the time \__xparse_grab_v_aux_loop_end: is expanded. xparse's code does \__xparse_add_arg:x { \tl_tail:N \l__xparse_v_arg_tl }, which removes the leading token from \l__xparse_v_arg_tl and then flushes it as an argument to the current macro. [...] – Phelype Oleinik Nov 30 '19 at 00:59
  • 2
    [...] My patch above changes that to the entire token list \l__xparse_v_arg_tl, plus its first token (\tl_head:N), so yes, if you did \test{hello} you'd end up with {hello{. If you insist, here's a version that works for \test{hello}: \cs_gset_protected:Npn \__xparse_grab_v_aux_loop_end: { \__xparse_grab_v_group_end: \__xparse_add_arg:x { \exp_not:V \l__xparse_v_arg_tl \str_if_eq:eeTF { \tl_head:N \l__xparse_v_arg_tl } { \c_left_brace_str } { \c_right_brace_str } { \tl_head:N \l__xparse_v_arg_tl } } }. – Phelype Oleinik Nov 30 '19 at 00:59
  • @PhelypeOleinik Thanks a lot. I think I will need an hour or five until I have retraced both the original definition and the patch in sufficient depth... ;-) – Ulrich Diez Nov 30 '19 at 01:10

0 Answers0