gusbrs / zref-clever

Clever LaTeX cross-references based on zref
LaTeX Project Public License v1.3c
11 stars 4 forks source link

[Question] zref-clever and cousins as replacement for cleveref #9

Closed 6601618158 closed 1 year ago

6601618158 commented 2 years ago

Sorry that this is a very soft question, probably better suited as an e-mail or message, but I haven't found a better way to do this, so here goes:

How bad of an idea is it to just take my existing LaTeX project (PhD thesis) that uses hyperref, bookmark, nameref, and cleveref, and

  1. lose nameref (functionality is included in zref, I think)
  2. replace cleveref with zref-clever
  3. replace all \labels with \zlabel, all \cref with \zcref, \lcnamecref with \zlabel[noref], etc.?

I just tried this out (I originally thought about redefining \label to \zlabel, etc., to save some work, but this would probably be a terrible idea, so did some searching & replacing, instead [EDIT: using zref-user seems to do just that, so maybe the idea wasn't that bad, after all…]) in a new git-branch, and to my great surprise, despite your warning in the documentation: not a single issue (after I fixed some incorrect usage of \zcref on my part).

I probably don't need any of the additional functionality that zref provides, but changing over resolved a bug with a \label that didn't work with pdfTeX and cleveref (but did with luaTeX and cleveref, so probably some weird encoding issue in a label name, or something), so it seems that zref is more robust, somehow… :thinking:

I also have a bit of a hard time in general finding a non-technical write-up about the usage of zref vs the traditional system (advantages, disadvantages, etc., especially for users as opposed to developers), and zref seems to live in the shadow somewhat, so I hope you have some insight into this.

gusbrs commented 2 years ago

How bad of an idea is it to just take my existing LaTeX project (PhD thesis) that uses hyperref, bookmark, nameref, and cleveref, and

  1. lose nameref (functionality is included in zref, I think)

  2. replace cleveref with zref-clever

  3. replace all \labels with \zlabel, all \cref with \zcref, \lcnamecref with \zlabel[noref], etc.?

I'd expect it not to be a bad idea at all. Indeed, zref-clever (plus zref-vario) aim at porting much of the functionality offered by the most prominent packages for the standard referencing system. And I think it's fair to say that it does cover the bulk of what cleveref, and varioref can do, and offers some spice of its own. nameref is covered by zref-titleref which integrates well. But I believe, and understand why it is so, that this is not really your main concern.

I just tried this out (I originally thought about redefining \label to \zlabel, etc., to save some work, but this would probably be a terrible idea, so did some searching & replacing, instead [EDIT: using zref-user seems to do just that, so maybe the idea wasn't that bad, after all…]) in a new git-branch, and to my great surprise, despite your warning in the documentation: not a single issue (after I fixed some incorrect usage of \zcref on my part).

I'm actually very glad to hear your experience with it went so smoothly. :-)

But a comment/recommendation in that regard. It is indeed not a good idea to simply \let\label\zlabel. Because there are places where you'll need \label and no other. Prominent example are amsmath math environments, but other corners may arise.

I probably don't need any of the additional functionality that zref provides, but changing over resolved a bug with a \label that didn't work with pdfTeX and cleveref (but did with luaTeX and cleveref, so probably some weird encoding issue in a label name, or something), so it seems that zref is more robust, somehow… thinking

Curious that you mention not needing zref additional functionality and gives an example of concrete problem you are facing for which the difference probably stems from zref's capacities. cleveref does not support labels with babel active characters (I'm supposing this is the reason of the problem you are facing), zref does, and zref-clever benefits from it.

But there are other user facing features that zref-clever provides which would be difficult to offer in the absence of the data flexibility of zref. For example, if you are using subcaption, you can just \zcref[ref=subref]{fig:1} to get a reference to the subfigure. This can also be used to build fancy ranges without the need to process the references to "strip the common prefix", and so on.

There are also things that zref-clever provides, which are actually quite independent of zref, that may or may not be important to you. If you write in German, there's noun declension support. For languages which have inflected articles and passing prepositions (e.g. European languages of Latin origin), there's also some support for avoiding being tripped by automation regarding the reference's surrounding material.

I also have a bit of a hard time in general finding a non-technical write-up about the usage of zref vs the traditional system (advantages, disadvantages, etc., especially for users as opposed to developers), and zref seems to live in the shadow somewhat, so I hope you have some insight into this.

Unfortunately, this is a little hard. The difference is either stated quite trivially, or quite technically. The trivial version is that the standard referencing system only allows for a hard-coded number of "fields" to be stored in a label, originally two, extended to five by hyperref. cleveref extends it further. zref works with the concept of a label being an extensible property list, to which you can add properties at will, and without fuss.

But well, you ask me, if hyperref and cleveref did extend the number of fields, what is the big deal? And that's where it gets technical. hyperref and cleveref can only do so by redefining core kernel commands, such as \label, \refstepcounter and so on. And the problem arises because these changes have to be somehow coordinated for different packages which want "a piece of the pie", and may break yet other ones which expect different definitions of these commands. So that's where much of the load order requirements and compatibility issues from these packages come from. zref-clever does not need to touch any of zref's or kernel commands, because zref is extensible out of the box.

Regarding "robustness" and "living in the shadow", zref is by Heiko Oberdiek, and currently maintained by the LaTeX Team, mainly Ulrike Fischer, as far as I get. It doesn't get any better than that (you cannot say the same of zref-clever though, but I'm working on a solid base, which is something). And this is quite the contrary of "shadow". True, despite the top-notch infrastructure, zref's user interface is spartan, to say the least. And that probably is a big factor in explaining why its user base is relatively small, and normally relegated to uses of one or another of its specialized features. But I hope zref-clever improves the situation in this area, and makes it more accessible and interesting to a wider audience.

But, back to what I think is your main concern. zref, and thus zref-clever, are arguably less subject to compatibility issues resulting from the technical issues mentioned above. On the other hand, the fact that the standard referencing system is, well, standard, means you can expect pretty much any package or document class which needs special handling of labels and references to support it. Unfortunately, you not expect the same for zref. So there's "less compatibility issues" for one cause, and "more compatibility issues" from the other. Unfortunately, I don't know well the actual limits of compatibility of zref, a lot of work went on so that is "wide enough", but I don't expect to be unrestricted. cleveref has documented a number of known limitations. zref-clever is not old enough to know them, it depends on people trying it out and testing stuff that I could not conceive.

Whether you should change to using zref-clever is really a question only you can answer, it depends on your requirements, your outlook, etc. Some things I think you should consider though:

  1. Some things may work better, and some things may work worse. You have to ponder the trade-offs. You should check if all packages you consider critical do work well. You can also take into consideration that zref-clever can be used in parallel with the standard referencing system, they are independent (technically, even with cleveref, you just have to disable the amsmath compatibility module for that). So if it "mostly works" and lets you down in just a few non-essential cases, you can fall back to \label and \ref with no problem.
  2. You mentioned the "despite your warning" in the docs, and I think you should consider that carefully too. As I've written there, the experimental status of the package doesn't mean I expect it to be "edgy". If you take a look of how thorough the regression test suite is, you'll find out one reason why your experiment went well. But I do not consider the package to be yet "settled", user interface included. That means breaking changes, which require you adjust your document may well occur, and you should be comfortable, or at least willing, to handle this kind of episode occasionally. cleveref, varioref and nameref (part of hyperref) on the other hand, are old an established packages, and excellent ones. So, if stability is of paramount concern to you, you should ponder this sternly.
  3. Know why your are changing, if you do. If you have concrete problems, or aims at new functionality, or are just plain curious or adventurous, its fine. If it is simply to handle a weird character in a label, I'd recommend you to rename the label instead.

That said, I do hope zref-clever and "cousins" are useful to you. :-)

6601618158 commented 2 years ago

I'd expect it not to be a bad idea at all. Indeed, zref-clever (plus zref-vario) aim at porting much of the functionality offered by the most prominent packages for the standard referencing system. And I think it's fair to say that it does cover the bulk of what cleveref, and varioref can do, and offers some spice of its own. nameref is covered by zref-titleref which integrates well. But I believe, and understand why it is so, that this is not really your main concern.

Ah, nice! I somehow expected things to be more delicate, so to speak. :smile:

I'm actually very glad to hear your experience with it went so smoothly. :-)

I hope this didn't come over as something like ‘I'm surprised this works, at all’. I think I just misinterpreted the warning to mean that it might not be a good idea to use the package specifically as a drop-in replacement, yet.

But a comment/recommendation in that regard. It is indeed not a good idea to simply \let\label\zlabel. Because there are places where you'll need \label and no other. Prominent example are amsmath math environments, but other corners may arise.

Okay, it seems I was a bit misinformed, then. I somehow also thought that using zref with the user option actually redefined \label to use \zlabel (probably in some clever way to avoid mishaps), but apparently it explicitly doesn't do that, so I don't know where I got that from…

By the way, do you have a reference for the amsmath problems? I couldn't find anything in the zref manual, except for a bug fix concerning amstext from 2022-03-08. Are these issues of the ‘it usually works, but in rare cases it might not’ kind? :grinning:

Curious that you mention not needing zref additional functionality and gives an example of concrete problem you are facing for which the difference probably stems from zref's capacities. cleveref does not support labels with babel active characters (I'm supposing this is the reason of the problem you are facing), zref does, and zref-clever benefits from it.

:D I guess I thought about something else when I wrote ‘additional functionality’, like absolute page numbers, and so on (which I don't really have a use case for, yet). The issue you describe seemed more like a bug fix to me.

I'm also not really sure what my problem was, exactly. I don't think I'm using any active characters in my labels (I think this usually happens with french and colons, right?), because I only use ngerman and british for babel, and I'm pretty sure I'm not using any of the German active characters (and AFAIK british doesn't define any). A sneaky Č sneaked in somewhere, though, but using luatex seems to have fixed that (which I only switched to because I didn't notice the Unicode in this one label). The error I got didn't seem to point there, though, but it's possible that's just a result of LaTeX's error messages not being terribly helpful all the time… Nonetheless, something like luatex or xetex is probably the future, anyway, so I don't mind using it, although I've fixed the label, already (, I think).

But there are other user facing features that zref-clever provides which would be difficult to offer in the absence of the data flexibility of zref. For example, if you are using subcaption, you can just \zcref[ref=subref]{fig:1} to get a reference to the subfigure. This can also be used to build fancy ranges without the need to process the references to "strip the common prefix", and so on.

There are also things that zref-clever provides, which are actually quite independent of zref, that may or may not be important to you. If you write in German, there's noun declension support. For languages which have inflected articles and passing prepositions (e.g. European languages of Latin origin), there's also some support for avoiding being tripped by automation regarding the reference's surrounding material.

Yeah, I bet there are a bunch of things that would be useful for me. I've just been using my current set of packages with all their limitations for so long, that a lot of things just don't come to mind. I'm probably not going to use much German in my document, but the features you mention might still come in handy at some point. :+1:

I also think that cleveref had a problem with the british option in babel (that is, not recognising it, I think, so I have to tell cleveref to use US(?)-english instead), that, AFAIR, didn't occur with zref-clever, so another advantage. :)

Unfortunately, this is a little hard. The difference is either stated quite trivially, or quite technically. The trivial version is that the standard referencing system only allows for a hard-coded number of "fields" to be stored in a label, originally two, extended to five by hyperref. cleveref extends it further. zref works with the concept of a label being an extensible property list, to which you can add properties at will, and without fuss.

But well, you ask me, if hyperref and cleveref did extend the number of fields, what is the big deal? And that's where it gets technical. hyperref and cleveref can only do so by redefining core kernel commands, such as \label, \refstepcounter and so on. And the problem arises because these changes have to be somehow coordinated for different packages which want "a piece of the pie", and may break yet other ones which expect different definitions of these commands. So that's where much of the load order requirements and compatibility issues from these packages come from. zref-clever does not need to touch any of zref's or kernel commands, because zref is extensible out of the box.

Thanks for the write-up! To me as a non-programmer, whenever I read the documentations of (and the occasional tex.stackexchange.com post about) cleveref and friends, especially when it came to limitations, the packages always kind of seemed like ‘hacks’ to me (very well-made ones, of course, but still…), so I think I get what you mean. :D

Regarding "robustness" and "living in the shadow", zref is by Heiko Oberdiek, and currently maintained by the LaTeX Team, mainly Ulrike Fischer, as far as I get. It doesn't get any better than that (you cannot say the same of zref-clever though, but I'm working on a solid base, which is something). And this is quite the contrary of "shadow". True, despite the top-notch infrastructure, zref's user interface is spartan, to say the least. And that probably is a big factor in explaining why its user base is relatively small, and normally relegated to uses of one or another of its specialized features. But I hope zref-clever improves the situation in this area, and makes it more accessible and interesting to a wider audience.

The ‘living in the shadow’ part was actually aimed more at utilisation by users (or the [perceived?] lack thereof), not so much at the quality of the package. I was actually very surprised when I first stumbled upon the package (by chance!), not only by how old it already was, who its author is, but also that you basically never see it mentioned anywhere (at least I don't). But maybe that's just a kind of core LaTeX problem. Users often seem to lack behind a lot when it comes to adopting new stuff and changing their ways. Case in point: you often still see people use $$ $$ for displaymath/\[ \], although LaTeX is almost 40 years old, now.

But, back to what I think is your main concern. zref, and thus zref-clever, are arguably less subject to compatibility issues resulting from the technical issues mentioned above. On the other hand, the fact that the standard referencing system is, well, standard, means you can expect pretty much any package or document class which needs special handling of labels and references to support it. Unfortunately, you not expect the same for zref. So there's "less compatibility issues" for one cause, and "more compatibility issues" from the other. Unfortunately, I don't know well the actual limits of compatibility of zref, a lot of work went on so that is "wide enough", but I don't expect to be unrestricted. cleveref has documented a number of known limitations. zref-clever is not old enough to know them, it depends on people trying it out and testing stuff that I could not conceive.

Whether you should change to using zref-clever is really a question only you can answer, it depends on your requirements, your outlook, etc. Some things I think you should consider though:

  1. Some things may work better, and some things may work worse. You have to ponder the trade-offs. You should check if all packages you consider critical do work well. You can also take into consideration that zref-clever can be used in parallel with the standard referencing system, they are independent (technically, even with cleveref, you just have to disable the amsmath compatibility module for that). So if it "mostly works" and lets you down in just a few non-essential cases, you can fall back to \label and \ref with no problem.

  2. You mentioned the "despite your warning" in the docs, and I think you should consider that carefully too. As I've written there, the experimental status of the package doesn't mean I expect it to be "edgy". If you take a look of how thorough the regression test suite is, you'll find out one reason why your experiment went well. But I do not consider the package to be yet "settled", user interface included. That means breaking changes, which require you adjust your document may well occur, and you should be comfortable, or at least willing, to handle this kind of episode occasionally. cleveref, varioref and nameref (part of hyperref) on the other hand, are old an established packages, and excellent ones. So, if stability is of paramount concern to you, you should ponder this sternly.

  3. Know why your are changing, if you do. If you have concrete problems, or aims at new functionality, or are just plain curious or adventurous, its fine. If it is simply to handle a weird character in a label, I'd recommend you to rename the label instead.

That said, I do hope zref-clever and "cousins" are useful to you. :-)

Thanks again for your detailed response! I'm pretty sure now that I'm going to switch to zref and zref-clever, after all. As a user of a ‘rolling release Linux’ I'm kind of used to stuff occasionally ‘breaking a bit’, and I usually try to ‘keep up with the times’ when it comes to software (although that doesn't seem to be the mentality of the typical LaTeX user :laughing:), so I guess this is a good fit. Switching back and forth also doesn't seem to be particularly difficult (mostly a bit of [regex-powered] search and replace), so the ‘danger’ is probably non-existent, anyway.

I'll try to report any problems I encounter in the future! And I'm very sorry for the late response!

gusbrs commented 2 years ago

I'm actually very glad to hear your experience with it went so smoothly. :-)

I hope this didn't come over as something like ‘I'm surprised this works, at all’.

Not at all, I really meant it.

Okay, it seems I was a bit misinformed, then. I somehow also thought that using zref with the user option actually redefined \label to use \zlabel (probably in some clever way to avoid mishaps), but apparently it explicitly doesn't do that, so I don't know where I got that from…

No, zref is really an independent system. I'm not sure where from you got the idea that zref-user redefines \label, and I was wondering if you had taken a look at its definition:

\newcommand*\zlabel{%
  \ifx\label\ltx@gobble
    \expandafter\ltx@gobble
  \else
    \expandafter\zref@wrapper@babel\expandafter\zref@label
  \fi
}%

What is actually going on there is Oberdiek being smart. There are several places in the "ecosystem" in which \label should not do anything for one reason or another. So, instead of waiting for all packages to do the same for \zlabel, he handles by making \zlabel get a "ride", it essentially says "if \label is disabled, disable \zlabel as well, otherwise, run \zref@label" which is the internal version of it.

By the way, do you have a reference for the amsmath problems? I couldn't find anything in the zref manual, except for a bug fix concerning amstext from 2022-03-08. Are these issues of the ‘it usually works, but in rare cases it might not’ kind? grinning

From zref, the closest to an "official statement" I think is: https://tex.stackexchange.com/a/402297. Which essentially says "amsmath does not support \zlabel", and it is true. This because amsmath has a lot of work to do to get this working for \label in the multiple passes the equations must go through, and it is highly unlikely that this will ever be made for \zlabel too, considering the stability requirements of the package.

What zref-clever does is make \label used inside an amsmath environment set both a \label and a \zlabel with the same name. The basic concept used by zref-clever is in my answer to the same question: https://tex.stackexchange.com/a/618438. The method is general, so it should work reliably (hopefully, that is, and do so as far as my testing went), you just have to use a \label there. Then you can make a \zref or \zcref reference to that label (or a \ref).

You have info about this in zref-clever's manual. Some examples in the how-tos section and the discussion about the amsmath compatibility module. And more details in the code documentation, if you so fancy.

Thanks for the write-up! To me as a non-programmer, whenever I read the documentations of (and the occasional tex.stackexchange.com post about) cleveref and friends, especially when it came to limitations, the packages always kind of seemed like ‘hacks’ to me (very well-made ones, of course, but still…), so I think I get what you mean. :D

It's really "the only way to do it". If you look at hyperref and cleveref source, you'll find that they redefine a lot of stuff from a lot of packages. The core of zref is made into an independent system, but even some of its modules have no alternative, for example zref-titleref has to do a similar work as nameref has to for captions, sections and so on.

Thanks again for your detailed response! I'm pretty sure now that I'm going to switch to zref and zref-clever, after all.

Welcome! :smile:

As a user of a ‘rolling release Linux’ I'm kind of used to stuff occasionally ‘breaking a bit’, and I usually try to ‘keep up with the times’ when it comes to software (although that doesn't seem to be the mentality of the typical LaTeX user laughing), so I guess this is a good fit. Switching back and forth also doesn't seem to be particularly difficult (mostly a bit of [regex-powered] search and replace), so the ‘danger’ is probably non-existent, anyway.

That's my view too. It should be reasonably safe and straightforward, as long as the user is competent enough (and willing) to handle these kinds of adjustments. Which, as you certainly know, is not always the case, and it is these whom the warning is really meant to safeguard.

I'll try to report any problems I encounter in the future!

Please do!