ifndef::foo,bar[] is not backwards compatible #1983

Open
jjaderberg opened this Issue Dec 30, 2016 · 0 comments

Projects

None yet

1 participant

@jjaderberg

Using ifdef with multiple attributes is backwards compatible in Asciidoctor, but ifndef is not. The negation has different scope.

With Asciidoc and comma-separated attributes ("any"), the negation in ifndef is applied to the union: if any of the attributes is defined, then false. This means that if ifdef would have evaluated to true for the same comma-separated list of attributes, then ifndef is false.

In Asciidoctor, the negation in ifndef is distributed: if any of the attributes is not defined, then true. This means that ifndef is not negating ifdef--indeed they can both be true at the same time for the same list of attributes.

Example AsciiDoc

= Ifndef if ifdef::asciidoctor[] diff from if ifndef::asciidoctor[]

ifdef::foo,bar[]
****
Foo.
****
endif::[]
ifndef::foo,bar[]
****
Bar.
****
endif::[]

Processing this document and defining one of the attributes gives different results with Asciidoc and Asciidoctor.

asciidoc -a foo foobar.adoc

will render the Foo. sidebar. ifdef::foo,bar[] is true because foo is defined. The Bar. sidebar is not rendered because ifndef::foo,bar[] is false, since the negation in ifndef is applied to the union--if any of the attributes is defined, then the expression as a whole is false.

Processing with AsciiDoctor

asciidoctor -a foo foobar.adoc

both Foo. and Bar. sidebars are rendered.

What about foo+bar?

Using a plus-separated list of attributes instead ("all"), the behavior is reversed. Adding to the example document a Foobar. sidebar under a ifndef::foo+bar[] condition:

ifdef::foo,bar[]
****
Foo.
****
endif::[]
ifndef::foo,bar[]
****
Bar.
****
endif::[]
ifndef::foo+bar[]
****
Foobar.
****
endif::[]

Asciidoctor will still render the Foo. and Bar. sidebars, but not the Foobar. sidebar. Asciidoc renders the Foo. and Foobar. sidebars.

Is this an intentional breaking change? It seems unnecessary since what it amounts to is swapping the meaning of ifndef::foo,bar[] and ifndef::foo+bar[].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment