extend condition syntax
See original GitHub issueIs your feature request related to a problem? Please describe.
Condition statements in official CSL take a single “match” attribute, which determines how the tests will be combined. The match attribute (all, any, none) applies to all tests within the statement: grouping of tests with separate match values is not possible. This makes combining different conditions unnecessarily complicated and often leads to highly nested and unreadable structures inside cs:if
.
Describe the solution you’d like
CSL-M has introduced an optional extended syntax for condition statement:
The alternative syntax may be applied to
cs:if
orcs:else-if
elements (the “parent node” in this description). The parent node must have no attributes, and a single cs:conditions node as its first child element. Thecs:conditions
node must have one or more cs:condition children. Thecs:condition
children each define a conditional statement with attributes specified in the CSL 1.0.1 schema and in this Supplement. Thecs:condition
statements are joined according to a mandatory “match” attribute oncs:conditions
.
Example:
<choose>
<if>
<conditions match="any">
<condition type="chapter"/>
<condition variable="container-title collection-title" match="nand"/>
</conditions>
<text macro="some-chapter-mac"/>
</if>
</choose>
CSL-M also adds match="nand"
which tests true if at least one of the tests or condition statements to which it applies returns false.
I suggest we implement this solution, or something similar.
** Current capabilities
Apart from match="nand"
, most (all?) tests can be done with standard CSL, but they may be less readable. This
<choose>
<if>
<conditions match="any">
<condition type="chapter"/>
<condition variable="container-title collection-title" match="nand"/>
</conditions>
<text macro="some-chapter-mac"/>
</if>
</choose>
needs a construction like this:
<choose>
<if type="chapter"/>
<text macro="some-chapter-mac"/>
</if>
<else-if variable="container-title collection-title" match="nand">
<text macro="some-chapter-mac"/>
<else-if>
</choose>
Now a real example (taken from chicago-note-bibliography.csl):
<macro name="collection-title">
<choose>
<if match="none" type="article-journal">
<choose>
<if match="none" is-numeric="collection-number">
<group delimiter=", ">
<text variable="collection-title" text-case="title"/>
<text variable="collection-number"/>
</group>
</if>
<else>
<group delimiter=" ">
<text variable="collection-title" text-case="title"/>
<text variable="collection-number"/>
</group>
</else>
</choose>
</if>
</choose>
</macro>
With the extended syntax that’s a bit simpler:
<macro name="collection-title">
<choose>
<if>
<conditions match="all">
<condition match="none" type="article-journal"/>
<condition match="none" is-numeric="collection-number">
</conditions>
<group delimiter=", ">
<text variable="collection-title" text-case="title"/>
<text variable="collection-number"/>
</group>
</if>
<else>
<group delimiter=" ">
<text variable="collection-title" text-case="title"/>
<text variable="collection-number"/>
</group>
</else>
<choose>
</macro>
Note that this extended syntax is not necessarily shorter. But it will be with a third condition, and I’d also say it is more readable and maintainability is better due to DRY (the example above needs to call the same macro twice).
Additional context see CSL-M supplement from where I have copied this request almost verbatim.
** Addendum: Possible extension of the extension:
We could go even further and allow multiple cs:conditions
.
Think of:
if ((x = 5 or y = 10) and ((a = 1 not b = 2) not (c = 3 or d = 4)))
<choose>
<if match="all">
<conditions match="any">
<condition type="chapter"/>
<condition variable="container-title collection-title" match="nand"/>
</conditions>
<conditions match="any">
<condition has-day="issued"/>
<condition date-range-variable"'issued" date-range-end='1900'/>
</conditions>
<text macro="some-other-mac"/>
</if>
</choose>
@bdarcus @bwiernik @adam3smith Thoughts?
Issue Analytics
- State:
- Created 3 years ago
- Comments:19 (19 by maintainers)
Top GitHub Comments
Ah, fair point. That will work.
conditions
would be a child element ofif
andelse-if
, not ofchoose