Will Robertson wrote: > Hi, > > In my original example writing > > \DeclareDocumentCommand \foo { ?{\my_sanitise:n} } { > % do whatever \foo is supposed to do with #1 > } > > I neglected to include how \my_sanitise:n would actually be written. And > I'm not too sure about that. If it ends up that \my_sanitise:n has to > write to a scratch variable anyway, then I'm not sure we've saved too much. [snip] > Good thinking. I prefer another modifier over an optional argument. Does > '>\preprocess' work for you? (I like having only a single token there, > but you'd be able to convince me otherwise.) I'd wondered about something similar. Looking at xdoc2l3, I think there are a couple of obvious post-processors. One is \detokenize given a "design" name (\Detokenize or \MakeString?), and the other is \MakeHarmless. Perhaps also a de-babel function to deal with active characters: \PunctuationOther? (Perhaps all of the functions should make it clear they are argument post-processors? \ArgDetokenize, \ArgMakeHarmless, etc.) In any case, I'd imagine any post-processor being a function of one argument. Internally, they'd do something with a temporary variable, then put the value of the variable back into the input of the underlying function defined by <code> in \DeclareDocumentCommand. I'd stick to post-processing if given the option. Pre-processing can lead to things which only work if the defined function is not nested (back with % again), and I'd prefer not to imply that can work. e-TeX makes post-processing catcodes possible, so saying "first the argument is grabbed, then it is modified" seems okay. >> Of course it is always hard to find the right balance between >> simplicity and >> features, but in this case my personal preference would be to have it >> included. > > I think adding this feature, possibly as "experimental" for now, would > be a good idea. Yes, provided we agree the other syntax in a more "decided" way that is fine. I'd also thought of ">" as the most obvious way to work this. (Insisting it goes before the specifier makes the code a lot easier to write, but if it is a problem we could put it after.) This still leaves how to handle long arguments. I've suggested two models: (1) Upper/lower-case for \long: \DeclareDocumentCommand \foo { o >\MakeHarmless M } \DeclareDocumentCommand \foo { o{default} >\MakeHarmless M } \DeclareDocumentCommand \foo { O >\MakeHarmless M } \DeclareDocumentCommand \foo { O{default} >\MakeHarmless M } (2) + for \long, upper-case for defaults on optional arguments: \DeclareDocumentCommand \foo { o >\MakeHarmless +m } \DeclareDocumentCommand \foo { O{default} >\MakeHarmless +m } \DeclareDocumentCommand \foo { +o >\MakeHarmless +m } \DeclareDocumentCommand \foo { +O{default} >\MakeHarmless +m } Both seem to look okay with the post-processing idea added in, I think. Based on Lars' comments about having a very clear syntax, can we agree on option (2)? If so, I can implement some of this and then see how it looks "in practice". > In terms of offering expandable optional arguments, I think Joseph's > "wright" that this can't possibly work with more complex argument types; > I might be wrong, however. Perhaps this can be something to revisit with > LuaTeX. I'm very reluctant to introduce something where we end up with a complex warning about what it is for. You can imagine using something like "e = expandable test for optional argument", but explaining what it is for and how to use it then becomes very complicated. If we really do want something like this, I'd think a separate function (\DeclareExpandableDocumentCommand) might be better. -- Joseph Wright