Great feedback! Thanks all around. Here are some thoughts and responses:
Rintze: Implicit suppression with cs:group won’t quite work,
unfortunately, since it’s about suppression, not alternative
rendering. For a specific use case, if the modular style decides that
a locator does not require a label (for a page, or for a paragraph in
OSCOLA, which is marked only by braces as [123]), we might want to
say, “Ibid. at [123],” whereas if it does supply a label, we might
want to say “Ibid. § 123.” If we use cs:group in the modular code, it
will deliver the label + the locator to the main style, where we will
have no way of determining if there is a label in there. If we deliver
the label alone (or not), the failed condition just renders nothing,
and we lack a means of testing for that.
Sebastian: A conditional would be possible, but as Aurimas says, a
straightforward approach to it would require that the macro be
rendered twice. (Also, it would require six additional lines of CSL
for each conditional, against zero additional lines for an attribute.)
Aurimas: Some of the double-rendering burden could be saved by
running the macro in the condition and then caching the result.
citeproc-js does some of that already, for name substitution. It gets
messy, though - and you only save the burden of one phase, the
generation of the output queue object. Flattening to a string does
indeed have to happen twice, there’s no way around that.
Phillip: The logic of cs:substitute is significantly different, and it
would be difficult to repurpose that code for this case. It depends on
the use of variables in each of the substitution candidates, which may
not be the case for arbitrary macros. It also suppresses substituted
variables through the remainder of the cite, which we wouldn’t want to
do for macro alternatives. A similar syntax could be used, with
separate code under the hood - something like:
<text macro="text-fragment">
<substitute>
<text macro="other-text-fragment"/>
</substitute>
</text>
I don’t see an advantage to that, though. In cs:substitute under
cs:names, the separate node allows us to tweak the parameters that
control name rendering, but a bare macro doesn’t have parameters to
tweak (apart from affixes, which are easy to control anyway). The
separate node doesn’t seem to contribute much to expressiveness.
The name “alt-macro” might not be the best, but all in all I’m still
liking a simple attribute for this edge case.
Frank