I’ve had some more thoughts about this since, and I think I have something even better, borrowing heavily from the Rust compiler/language evolution process, which I am clearly a fan of. Essentially:
- Have a list of all independent features your compiler supports
- Have an optional top-level
<features> <feature name="xxx" /> ... </features>
section in a style to require + enable individual ones as necessary. - Features are unstable and not guaranteed to be around forever. Use at your own risk.
- Throw errors if you do not support a feature that a style says it requires
- Throw errors if a style uses a syntax-based feature it does not declare (some features might merely change the output without any new syntax)
- Canonical feature naming for common implementation is based on tracking issues, so multiple engines can agree on the name of a feature even if they differ in implementation/progress/etc.
- Eventually, either accept features because they make it into the CSL spec, or remove them. Accepted features no longer need to be declared in the
<features>
section, and removed features throw errors. - Have a shorthand
<feature name="csl-m" />
that enables all the features that make up CSL-M, as that list would be quite long. That would make your job pretty easy if you wanted: only support the one feature, “csl-m”. Doing individual flags may be quite a lot of work, although if there is any low-hanging fruit like self-contained singleif (cslM) { ... }
blocks, it would help to convert them.
citeproc-rs features defined here – In styles they are kebab-case, but rust identifiers can’t be so a conversion is done to snake_case at runtime. Technically, the engine only supports a few of those, so most should be commented out. I have one removed feature just to try it out, although I do think form="abbreviated"
would have been better .
In action – You can see citeproc-rs yell at you with parse-time errors if you delete either of those lines and keep the <conditions>
block as-is. Those ones also know which features you could enable to use the syntax, but this wouldn’t be universal.
The <features>
section should be an addition to the spec in itself, hopefully 1.1. The only reason for that is so you can get meaningful this engine does not support features
/specific feature X
errors, and not unknown element <features>
. Individual feature flags should not be part of the spec, only the syntax for declaring them. It would be great to have features 1:1 GitHub tracking issues in a single repo. This is so people who use them can be linked to their status, and (importantly) be provided with information if a feature they required was removed. (As Rintze noted, evolution issues are in the wrong place at the moment, but GitHub seems to have built an issue-mover in beta.)
Some benefits of such a scheme are:
- People who need things faster, like the beneficiaries of Propachi, can live on the edge, but they are forced to document what’s different about the CSL they’re speaking.
- You can grep over the styles repository to see if anyone is relying on a feature. You don’t have to eventually accept every feature that is used, but it helps to know.
- You know what modifications an edgy style you’ve found needs before it will run on stable-only again.
Let me know what you think, and if there are any difficulties I haven’t imagined.