checking for suppressed variables used in cs:substitute

Hi,

there is an issue with a style (chicago-author-date shipped with pandoc,
which comes from the test-suite repository) and the way is uses
.

This is the issue, from the citeproc-hs perspective: according to the
specification “[s]ubstituted variables are suppressed in the rest of the
output to prevent duplication.” This style uses the variable “editor” as
a substitute and then checks if it is set, or if it is set the variable
"author" or the variable “translator”. If none of them is set then
"Anon." is printed. Author and translator are not set and editor has
been suppressed. Which, in citeproc-hs sense means unset.

I think it is a style bug (I do not think chicago-author-date belongs to
the best coded styles), but it may also be my wrong interpretation of
what “suppressed” means. What do you think?

This is the relevant style code:











with “anon” being:

andrea

Been a long day, so take this FWIW …On Thu, Nov 17, 2011 at 4:17 PM, andrea rossato <@andrea_rossato2> wrote:

Hi,

there is an issue with a style (chicago-author-date shipped with pandoc,
which comes from the test-suite repository) and the way is uses
.

This is the issue, from the citeproc-hs perspective: according to the
specification “[s]ubstituted variables are suppressed in the rest of the
output to prevent duplication.” This style uses the variable “editor” as
a substitute and then checks if it is set, or if it is set the variable
"author" or the variable “translator”. If none of them is set then
"Anon." is printed. Author and translator are not set and editor has
been suppressed. Which, in citeproc-hs sense means unset.

I think it is a style bug (I do not think chicago-author-date belongs to
the best coded styles), but it may also be my wrong interpretation of
what “suppressed” means. What do you think?

This is the relevant style code:











with “anon” being:

WRT to the style, I think it should work, but that it would be better
if the fragment got folded in at the end of the
substitute element.

I don’t think citeproc-hs should be printing “anon” unless there is no
author, editor, or translator.

Bruce

First, I think the style should just use

 <substitute>
   <text macro="editor" />
   <text macro="translator" />
   <text macro="anon"/>
 </substitute>

which eliminates the need for the conditional in the “anon” macro.

I don’t think we have ever discussed what the behavior of the conditional
should be in case of a suppressed variable, and I think a case can be made
for both choices. Assuming that suppressed variables are “unset” in
conditionals gives a bit more flexibility in coding style logic, but
ignoring suppression would make styles easier to debug.

RintzeOn Thu, Nov 17, 2011 at 4:17 PM, andrea rossato <@andrea_rossato2>wrote:

Hmm …

It’s been awhile since I’ve worked on my implementation, but I dealt
with this sort of thing by, whenever I need to print a variable,
removing it from the data hash, with code like:

if variable:
    if variable in reference:
        content = reference.pop(style_node.get('variable'))

So in this case, if an editor name gets printed (doesn’t matter how),
it gets removed from the data hash, and so is not present for later
printing. So I guess I’m implicitly making the same assumption that
Andrea has made; that the bug would be in the style.

But that might be confusing for style authors.

Bruce

I just made that change in the style.

Bruce

If we are going to specify this, then it will be necessary to define when exactly a variable is substituted. Looking at the style in question, the first substitution is a text macro (!) called ‘editor’ – at what point should a processor decide which variable was used as a substitute? IMO the repression of substituted variables should be limited to a case like:

Here it is immediately clear that the editor variable is used for the author variable; is it necessary to force the processor to expand nested macros to infer which variable was used as a substitute? Frank and Andrea seem taken the effort to implemented it this way, however, I wonder if that isn’t too complicated.

Another issue I noticed: if editor is used as a substitute for author (and is subsequently repressed), I still think that the conditional check ‘author or editor or translator’ should equal true, because we do have one value: either the editor, or, if we say that editor is unset/repressed it follows that we now have a valid author value, because that’s what editor was used for.

Sylvester

Sylvester Keil <@Sylvester_Keil> writes:

I don’t think we have ever discussed what the behavior of the
conditional should be in case of a suppressed variable, and I think a
case can be made for both choices. Assuming that suppressed variables
are “unset” in conditionals gives a bit more flexibility in coding
style logic, but ignoring suppression would make styles easier to
debug.

If we are going to specify this, then it will be necessary to define
when exactly a variable is substituted. Looking at the style in
question, the first substitution is a text macro (!) called ‘editor’ –
at what point should a processor decide which variable was used as a
substitute? IMO the repression of substituted variables should be
limited to a case like:

Here it is immediately clear that the editor variable is used for the
author variable; is it necessary to force the processor to expand
nested macros to infer which variable was used as a substitute? Frank
and Andrea seem taken the effort to implemented it this way, however,
I wonder if that isn’t too complicated.

I implemented cs:substitute so to explicitly consume used variables. See
the function “consuming” in src/Text/CSL/Eval/Common.hs which, as you
may see, it does not expand nested macros, but forces the variable to
get a Value Empty after being used when evaluating a cs:substitute
element.

In other words, variables are stored in a global state together with
another Boolean variable; when this is True retrieved variables are
immediately emptied.

Another issue I noticed: if editor is used as a substitute for author
(and is subsequently repressed), I still think that the conditional
check ‘author or editor or translator’ should equal true, because we do
have one value: either the editor, or, if we say that editor is
unset/repressed it follows that we now have a valid author value,
because that’s what editor was used for.

I do not see it this way: author has no value and so a substitute,
another variable, is used instead. As a result, the act of using it
suppresses it, which means that the variable will return no value for
any other call in the cs:layout element.

Andrea

Sylvester Keil <@Sylvester_Keil> writes:

I don’t think we have ever discussed what the behavior of the
conditional should be in case of a suppressed variable, and I think a
case can be made for both choices. Assuming that suppressed variables
are “unset” in conditionals gives a bit more flexibility in coding
style logic, but ignoring suppression would make styles easier to
debug.

If we are going to specify this, then it will be necessary to define
when exactly a variable is substituted. Looking at the style in
question, the first substitution is a text macro (!) called ‘editor’ –
at what point should a processor decide which variable was used as a
substitute? IMO the repression of substituted variables should be
limited to a case like:

Here it is immediately clear that the editor variable is used for the
author variable; is it necessary to force the processor to expand
nested macros to infer which variable was used as a substitute? Frank
and Andrea seem taken the effort to implemented it this way, however,
I wonder if that isn’t too complicated.

I implemented cs:substitute so to explicitly consume used variables. See
the function “consuming” in src/Text/CSL/Eval/Common.hs which, as you
may see, it does not expand nested macros, but forces the variable to
get a Value Empty after being used when evaluating a cs:substitute
element.

In other words, variables are stored in a global state together with
another Boolean variable; when this is True retrieved variables are
immediately emptied.

Another issue I noticed: if editor is used as a substitute for author
(and is subsequently repressed), I still think that the conditional
check ‘author or editor or translator’ should equal true, because we do
have one value: either the editor, or, if we say that editor is
unset/repressed it follows that we now have a valid author value,
because that’s what editor was used for.

I do not see it this way: author has no value and so a substitute,
another variable, is used instead. As a result, the act of using it
suppresses it, which means that the variable will return no value for
any other call in the cs:layout element.

If substituted variables are unset globally, does that mean that the
result of a conditional test for the variable value depends on whether
the test is made before or after the cs:names element is rendered? If
so, that might be a little confusing for style authors.

Frank Bennett <@Frank_Bennett> writes:> On Fri, Nov 18, 2011 at 9:19 PM, andrea rossato <@andrea_rossato2> wrote:

I do not see it this way: author has no value and so a substitute,
another variable, is used instead. As a result, the act of using it
suppresses it, which means that the variable will return no value for
any other call in the cs:layout element.

If substituted variables are unset globally, does that mean that the
result of a conditional test for the variable value depends on whether
the test is made before or after the cs:names element is rendered? If
so, that might be a little confusing for style authors.

Well, this is the problem I rose with this thread, actually.

I do not think it is that confusing for style authors, though. Or
better, I would find a bit more confusing the possibility of a
conditional returning true and the variable not being rendered, wouldn’t
you?

Andrea

Frank Bennett <@Frank_Bennett> writes:

I do not see it this way: author has no value and so a substitute,
another variable, is used instead. As a result, the act of using it
suppresses it, which means that the variable will return no value for
any other call in the cs:layout element.

If substituted variables are unset globally, does that mean that the
result of a conditional test for the variable value depends on whether
the test is made before or after the cs:names element is rendered? If
so, that might be a little confusing for style authors.

Well, this is the problem I rose with this thread, actually.

I do not think it is that confusing for style authors, though. Or
better, I would find a bit more confusing the possibility of a
conditional returning true and the variable not being rendered, wouldn’t
you?

Not really, no. Since CSL fails gracefully on an unsuccessful attempt
to render an element, a style wouldn’t wrap a names element to render
editor (say) in a conditional test for the presence of an editor. I
think the way style authors think about it is to condition the form of
a cite on the variables presented on the item. It’s easier to
understand if the condition yields the same result wherever it is
invoked.

From the point of view of a style author, I would think that the condition, does either of ‘author’, ‘editor’ or ‘translator’ exist should be true, even if one of the variables was substituted by one of the others. Let’s think about it this way: to my understanding, the reason for the substitution is that, given a style that would normally print both editor and author fields there will be no duplication if one of the fields is missing and substituted by the other one. However, that still means that one of the two fields exists (it was just repressed from being printed a second time), so it seems only logical to me that a condition that asks whether one or the other exists should be true.

Consistency is more complicated though. Because the conditional in question queried both variables in question, it is not so important which of them returns true, as long as one of them does. However, if we want full consistency then the substitution cannot repress a value from conditionals at all (i.e., what if the conditional queried only the author field or the editor field, but not both), or the cite processor would have to process the style in two-passes, using a first pass to make substitutions.

I think this is altogether too complicated. Either suppression of variables should be applied only to printing of variables (not conditions), or it should be implemented like Andrea suggests, however, either the substitute or the variable that was substituted should be considered to exist after the substitution (leading to potentially inconsistent conditional results); it just does not make sense to me that suddenly both variables should be gone after the substitution.

Sylvester

My vote is for the former (don’t have suppression affect conditionals).

RintzeOn Sat, Nov 19, 2011 at 4:53 AM, Sylvester Keil <@Sylvester_Keil>wrote:

To repeat: I think the language of “suppression” is itself confusing,
and that it might need revising. I don’t have any particular
suggestion ATM though.

Bruce