siunitx
siunitx copied to clipboard
`free-standing-units=false` still defines macros
When upgrading from TeXLive 2021 to 2024, I spent hours debugging an LaTeX Error: Command \C already defined..
Turns out this is reproducible with:
\documentclass{standalone}
\usepackage[free-standing-units=false]{siunitx}
\begin{document}
\newcommand{\C}{\mathcal{C}}
foo
\end{document}
Apparently this package defines the macros even when explicitly disabling free-standing-units. However, the documentation claims that it doesn't:
https://github.com/josephwright/siunitx/blob/549cad913591b92a3a199b7477a325866303bf29/siunitx.tex#L2459-L2460
It's quite annoying if new (single-letter!) macros are defined even if the user tries to shield themselves against it by disabling free-standing-units.
I will tighten up the docs here.
The free-standing-units option is about whether something like \metre is set up to 'work' outside the scope of the unit argument to \unit, \qty, etc.: it is off as-standard as I don't think it's a great input syntax.
However, that doesn't affect the need to have the document commands defined for everything - there are technical reasons. So what happens is siunitx checks at the start of a document if the unit commands exist - and if they don't creates holders - which error if used out-of-context.
If your example, you are defining a document command after the preamble, which is what catches siunitx out. In a well-structured LaTeX document, all of the document commands should be created before the document starts - they after all define the document. So you can fix with a simple move of your document command to the preamble.
(There's been no change in the approach - it's only that v2 didn't have an abbreviation for \degreeCelsius. You'd have had an error in v2 if you'd tried to define for example \metre.)
However, that doesn't affect the need to have the document commands defined for everything - there are technical reasons.
What's the reason? I would think that they could be defined in a local group just in \unit and \qty.
This comment from the issue that introduced \C also sounded like it would defined only in such group, but maybe I misunderstood.
If your example, you are defining a document command after the preamble, which is what catches
siunitxout. In a well-structured LaTeX document, all of the document commands should be created before the document starts - they after all define the document. So you can fix with a simple move of your document command to the preamble.
I also noticed that difference, but it's not possible/desirable to always do that. For example, I use subfiles to heavily modularize a large document (but the same applies to all environment-local macros) and only define convenient single-letter macros in small scopes instead of polluting the global namespace.
However, that doesn't affect the need to have the document commands defined for everything - there are technical reasons.
What's the reason? I would think that they could be defined in a local group just in
\unitand\qty. This comment from the issue that introduced\Calso sounded like it would defined only in such group, but maybe I misunderstood.
In expansion contexts, a non-defined unit command would lead to a undefined control sequence error. One cannot arrange that \qty, etc., are always 'in control' in such contexts, thus it's a requirement that there is some non-error definition in these places.
If your example, you are defining a document command after the preamble, which is what catches
siunitxout. In a well-structured LaTeX document, all of the document commands should be created before the document starts - they after all define the document. So you can fix with a simple move of your document command to the preamble.I also noticed that difference, but it's not possible/desirable to always do that. For example, I use
subfilesto heavily modularize a large document (but the same applies to all environment-local macros) and only define convenient single-letter macros in small scopes instead of polluting the global namespace.
LaTeX documents should always have commands defined in global scope even if they are locally modified - as document commands define LaTeX.
I will tighten the docs here for the next release