Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The package doesn't provide means for deciding whether properties are to be maintained globally or locally #16

Open
Ulrich-Diez opened this issue Mar 11, 2023 · 2 comments

Comments

@Ulrich-Diez
Copy link

The package doesn't provide means for deciding whether properties are to be maintained (initializing via \zref@newprop, changing values via \zref@setcurrent) globally or locally.

Most of the time I would like a command like \zref@setcurrent to act globally when changing values of properties from within environments.

Most of the time I would like a command like \zref@newprop to introduce new properties and their defaults globally.

But effects of \zref@setcurrent and \zref@newprop seem in any case to be restricted to the current scope, which may be a local scope.

@u-fischer
Copy link
Contributor

allocations of properties with \zref@newprop should be done in the preamble and so are always "global", quite similar to other allocations, e.g. with \newcount. Unless you have a very good use case I would say it is a coding error if this happens in a group.

That \zref@setcurrent works locally is quite in line with the standard kernel label behaviour: \@currentlabel is set locally too. While I agree that there can be use cases for a global setting (e.g. \@currentHref from hyperref is set globally), I don't think that you need it in your example on tex.sx. \zref@setcurrent is useful if the value comes from various sources, as with \@currentlabel which records a variety of counters, but if you want to store only a specific counter or variable you can setup the property so that it simply does this and do not need to make a detour with \zref@setcurrent.

@Ulrich-Diez
Copy link
Author

Ulrich-Diez commented Mar 12, 2023

allocations of properties with \zref@newprop should be done in the preamble and so are always "global", quite similar to other allocations, e.g. with \newcount. Unless you have a very good use case I would say it is a coding error if this happens in a group.

Now that I have taken a closer look at the code of the zref package, I think the attempt of defining a property within a local scope is not a design flaw related to the user's intended general way of handling certain data, but is a coding error related to disregarding some technical peculiarities of TeX itself which limit the ways of how zref itself could be implemented at all.

I should have guessed right away how matters can be, but sometimes I am not in the condition for making good guesses.

Thus I wish to apologize for having raised at all the matter of restricting the defining of properties to a local scope.

You know about the details, of course, but maybe other people are reading along who stumble across the problem:

Seems the user documentation of zref does not explicitly point out:

With the LaTeX 2e kernel cross referencing commands like \ref themselves don't require \@currentlabel and the like to be defined. One could do \begingroup\makeatletter\let\@currentlabel=\UndeFineD \ref{some label}\endgroup.

But with zref the being defined of a property is a prerequisite not only for assigning values to it later in the current LaTeX run, but also

  • for having LaTeX extract from a zref label a value which that property had at some moment in time during the previous LaTeX run and which is stored in the zref label

  • and for having LaTeX check whether a value which that a property had at some moment in time during the previous LaTeX run is stored in a zref label at all.

The package also provides methods for doing the above mentioned things which are based on expansion only.

With zref's data structure schema this in turn requires an (internal) extraction function specific to that property to be available along with each property at those moments when one of the above mentioned things is to be done with it. (The user usually doesn't need to cope with extraction functions).

As extraction functions are defined along with properties, extraction functions are missing during the LaTeX run in these moments in time where properties are not defined yet.
If you allow locally definable properties, the extraction functions of properties that are defined locally only will be missing also when the scope where the properties are defined is closed.

In the token sequence consisting of the data stored as a zref label, the presence of the value that a particular property had at some moment in time during the previous LaTeX run is indicated by the presence of a control word token whose name corresponds to the name of the property in question.

Thus the desire for expansion based methods leads to the problem of checking only by means of expansion whether a token sequence contains a particular control word token in such a way that it is not enclosed in curly braces/in such a way that it is not placed somewhere between an explicit character token of category 1 and a matching explicit character token of category 2.
To my knowledge, with non-LuaTeX TeX-engines this can be done reliably only by means of macros that process delimited arguments where the control word token whose presence is to be checked is a component of one of the argument delimiters. That's why with zref's property management such a macro is needed as extraction function with each property. That's also why I should have guessed right away that defining properties locally is not a good idea with zref.

That \zref@setcurrent works locally is quite in line with the standard kernel label behaviour: \@currentlabel is set locally too.

Taking the fact that properties and their defaults are defined in terms of \global and that properties are to be defined globally right at the beginning of the LaTeX run for ensuring their extraction functions to be available when/if needed in the LaTeX run I don't think that in this matter being in line with the standard kernel behavior is a good reason for denying means for leaving the line by setting values of properties globally.

\zref@setcurrent is useful if the value comes from various sources

Indeed.This, however, does not contradict the statement that the possibility of a property also being the "source" is nice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants