Macro condition

I’m looking at implementing a “small” extension in citeproc-js that
seems necessary for modular style support.

Code calling a modular macro may need to know whether the macro
produced output, without regard to its internals. One such case is
critical for modular support: the modular code may return a bare term
(such as “§”) to be applied as a label, which is sometimes returned
empty (as for a “page” locator). In this case, the calling style may
wish to add a connecting label:

Ibid. at 123.

versus
Ibid. § 45.

The supplementary connecting string (“at” in this example) needs to be
under the control of the calling style, but we lack a conditional that
can identify whether the remote macro generating the label produced
output. The solution I’m looking at would work like this:

<text macro="juris-label" alt-macro="the-word-at"/>

I don’t think this will be useful in self-contained styles, but in the
modular architecture it seems like a minimal solution to what would
otherwise be an awkward problem.

Frank

Sorry, I don’t follow. Why is this use case not covered by “cs:group
implicitly acts as a conditional: cs:group and its child elements are
suppressed if a) at least one rendering element in cs:group calls a
variable (either directly or via a macro), and b) all variables that
are called are empty.”
(http://citationstyles.org/downloads/specification.html#group)?
Wouldn’t that extend to modular macros?

Rintze

couldn’t we stay closer to existing syntax and just allow a test for

which returns true if and only if the string returned by the macro is
non-empty?

What Franks wants is

  • if the macro returns a strong --> use the string
  • else, call another macro
    I don’t see how the implicit conditional of groups would help here, since
    you can’t actually test for them?

In a non-modular set-up, there are a number of ways to do this–e.g.
normally we’d just handle the “at” in the same macro as the §. But if you
want to modularize that, that’s no longer possible.
Correct me if I’m misunderstanding this, Frank.

  1. I don’t like the name “alt-macro”.
  2. It looks for me like a similar construct as the “substitute” in the
    names node:
    http://citationstyles.org/downloads/specification.html#substitute
  3. More general a test as Sebastian propose could also work.
    (4. I am somehow missing, why the alternative macro has to be outside the
    main macro, maybe more context would help at least me.)2015-02-25 21:29 GMT+01:00 Sebastian Karcher <@Sebastian_Karcher>:

The problem with the if test is that you would end up calling the macro
twice. Once to check it and then to generate the content. Not an issue for
simple macros, but would be unnecessary overhead otherwise. Though
depending on how flexible you want this mechanism to be, there might not be
another way.

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

This is another case I just don’t have the time/energy to wrap my head
around fully.

I also agree with others the syntax seems inconsistent with the current
design.

But … another two, related, questions:

Implementation complexity?

Bigger: the design of CSL has always been premised on monolithic styles.
Why shouldn’t we be leery of the potential can of worms this opens up?

This is another case I just don’t have the time/energy to wrap my head
around fully.

I also agree with others the syntax seems inconsistent with the current
design.

But … another two, related, questions:

Implementation complexity?

It took few hours to work out the details for modular loading and
alt-macro, but both have been done for citeproc-js. In a sense,
citeproc-js is a good test case for complexity because its code is not
the cleanest. (Implementing alt-macro forced me to do some
optimization in the processor code, but that needed doing anyway.)

Basically once you have stable code for macros and cs:group, extending
a processor to support modular loading and alt-macro should be pretty
straightforward.

Bigger: the design of CSL has always been premised on monolithic styles. Why
shouldn’t we be leery of the potential can of worms this opens up?

Indeed. I don’t know about other applications, but modular loading is
absolutely needed for legal referencing. Style manuals typically
incorporate legal citation rules by reference; it is a natural move
for CSL to do the same.

I’m probably still missing something, but how about just

?

right, that’s why for regular styles, this is no problem. Frank, however,
wants to be able to render the “at” in a different macro than the label
variable (because both can take different forms in different styles). So
this really only applies to modularization.

right, that’s why for regular styles, this is no problem. Frank, however,
wants to be able to render the “at” in a different macro than the label
variable (because both can take different forms in different styles). So
this really only applies to modularization.

Exactly as Sebastian says. This is not logically necessary in a
self-contained style.

  • Aren’t most of the attributes and names in CSL written out instead of
    abbreviated? For example we have the attribute “initialize-with” or “
    limit-day-ordinals-to-day-1”. How about then also to write it out here,
    i.e. “alternative-macro”? (In German “alt” is “old” which is slightly
    different from “alternative”.)

  • Let me try to continue on Sebstian’s conditional approach: We would test
    for macro A, if successfully then call macro A otherwise call macro B.
    Well, in theory we could also call macro C in the success case, but this
    seams to make no sense, right? However, we could continue with different
    else cases. Is it possible to have more than two cases A, B? How would you
    do that? Second-alternative-macro?

  • An example outside from legal law:

with

It looks like we could also simplify some conditional if construction with
this method (but have to enjoy more modularized styles).2015-02-26 4:40 GMT+01:00 Frank Bennett <@Frank_Bennett>:

Do we really expect a significant performance hit by rendering a few
macros twice? Frank, do you expect to need this feature many times
within a single legal style? Would the verbosity of a conditional
really be a significant issue? (alternatively, maybe we could get rid
of cs:choose? Not entirely sure if RELAXNG allows for that, though,
which is probably the main reason we have it.

Rintze

P.S. Frank wrote a description of modular style support in MLZ at


(although I think the examples contain a few typos).

For what it’s worth, Frank’s proposal would be easy to add to
citeproc-ruby and I’d be happy to support it.

Sylvester

signature.asc (181 Bytes)

Philipp,

Spelling out the attribute name is a good idea. Your comment on the
possible quandaries in the syntax of an “alternative-macro” reveals a
problem that does need to be addressed in the proposal.

As Sebastian spotted, this construct is needed only to cope with a
particular problem that arises when running a macro from an external
module. We want run some local fallback code when the macro produces
no output, but we do not know what the macro contains, so we cannot
test for its preconditions: the only option is to check whether it
has, in fact, output something.

The single “alternative-macro” attribute is not well suited to onward
if-then-else condition processing. You could string them together in a
daisy-chain, but the logic would quickly become hard to follow. We
really don’t want to let people go there.

I didn’t particularly like this approach because of the verbosity, but I’ll
throw it out there anyway as a potential alternative (maybe it can give you
additional ideas). You could do something like the following (borrowing
from RDF):
(or to take directly from RDF )

  • You can also have something that would render only if all elements evaluate
    to something

  • </all
  • I didn’t particularly like this approach because of the verbosity, but I’ll
    throw it out there anyway as a potential alternative (maybe it can give you
    additional ideas). You could do something like the following (borrowing from
    RDF):
    (or to take directly from RDF )

  • You can also have something that would render only if all elements evaluate
    to something

  • Aurimas,

    This is interesting - thanks for posting it. For general testing for
    macro output, this would be much better (and less verbose) than
    embedding tests in condition statements. It’s a -like
    approach

    If I read the atmosphere right, though, I think there is consensus
    that a general method of testing for output is not necessary (and I
    agree with that myself). For the very limited use case of modular
    macro output, the attribute thing provides enough coverage.

    I still think we need to start with first principles: do we really want to
    make CSL “modular”?

    Or do we merely want to make it easy for its most complete and widely used
    implementation to add the benefits of such modularity?

    Do these benefits only really apply to the legal use case, or are they
    potentially much more general?

    How do we imagine this unfolding over next five years vis-à-vis style
    content?

    How will it intersect with things like repositories?

    My initial answer to first question is no, and that maybe this feature
    should not be core to CSL, but an extension attribute. But this would also
    have downsides, and opens up further questions (like, what’s our long term
    strategy on CSL evolution, extensions, etc.?).

    Bruce

    I still think we need to start with first principles: do we really want to
    make CSL “modular”?

    Or do we merely want to make it easy for its most complete and widely used
    implementation to add the benefits of such modularity?

    Do these benefits only really apply to the legal use case, or are they
    potentially much more general?

    How do we imagine this unfolding over next five years vis-à-vis style
    content?

    How will it intersect with things like repositories?

    My initial answer to first question is no, and that maybe this feature
    should not be core to CSL, but an extension attribute. But this would also
    have downsides, and opens up further questions (like, what’s our long term
    strategy on CSL evolution, extensions, etc.?).

    I’ll step aside here, as I have a clear interest that is well known.
    These will be questions for the rest of the group to settle.

    Frank