pietvo / fancyhdr

The LaTeX package 'fancyhdr'
35 stars 9 forks source link

extramarks breaks LaTeXs mark mechanism from 2022 #19

Open FrankMittelbach opened 1 week ago

FrankMittelbach commented 1 week ago

The extramarks package augments the legacy LaTeX mark mechanism by making every mark containing 4 brace groups rather than 2. This means it has to overwrite the LaTeX commands \markboth and \@markright (as well as \leftmarkand \rightmark. However, in 2022 LaTeX introduced a new mark mechanism (initially alongside with the old) that allows for arbitrary many independent marks. To allow both old and new the kernel definitions for \markboth and \markright were changed.

Unfortunately that change wasn't incorporated into extramarks, so loading this packages basically breaks standard LaTeX capabilities as of 2022.

A correct definition in extramarks could look as follows:

\ExplSyntaxOn
\DeclareRobustCommand*\markboth[2]{%
  \begingroup
    \let\label\relax \let\index\relax \let\glossary\relax
    \expandafter\@markboth\@themark{#1}{#2}%
    \@temptokena \expandafter{\@themark}%
% 3 new lines from 2022
    \mark_insert:nn{2e-left}{#1}
    \mark_insert:nn{2e-right}{#2}
    \tl_if_empty:nF{#2}{ \mark_insert:nn{2e-right-nonempty}{#2} }
    \mark{\the\@temptokena}%
  \endgroup
  \if@nobreak\ifvmode\nobreak\fi\fi}
\ExplSyntaxOff

With the above correction the kernel and extramarks could coexist peacefully. However, with the new mark mechanism of LaTex the functionality of extramarks could in fact be provided much simpler by using a \NewMarkClass --- which is a) more flexible as it is not updating other marks by reinserting their values and it is offering a true top mark, somthing that wasn't possible with LaTeX (or extramarks) in the past.

So my suggestion would be to a) make the above correction

b) or better reimplement extramarks interface using two new mark classes

c) suggest retiring extramarks for new documents in favor of the LaTeX method interface by using two extra mark classes

In fact, our plans are to simplify \markboth and friends in the 2025-06-01 release of LaTeX and drop the legacy marks from the kernel so that the kernel definition becomes simply

\ExplSyntaxOn
\DeclareRobustCommand*\markboth[2]{%
    \mark_insert:nn{2e-left}{#1}
    \mark_insert:nn{2e-right}{#2}
    \tl_if_empty:nF{#2}{ \mark_insert:nn{2e-right-nonempty}{#2} }
\ExplSyntaxOff

which suggests going for b) and c).

pietvo commented 1 week ago

I already have a new extramarks implementation which uses method (b). It has not yet been released, however. It ma be a good idea to also implement (a) in the current (legacy to be) implementation. I'll look into that.

pietvo commented 1 week ago

My plan of attack now is:

  1. Implement the change proposed by Frank above (a).
  2. Finish my implementation of extramarks (version 5.0) with the new marks mechanism (b). I can't release this yet because it breaks with multicol. As soon as I have been able to test it with the new multicol, and a release of this multicol is near, I will release the new version. I will keep a fallback to the old version.
  3. In the documentation I will recommend using the new marks mechanism. In fact, I already have done this in the 5.0 documentation, and I have changed some of the examples already to use the new marks instead of extramarks
FrankMittelbach commented 1 week ago

sounds like a plan, thanks. The updated versions should show up in the next dev release which is coming soon and then "officially" in the 2025-06-01 release so plenty of time to see that everything works.

pietvo commented 1 week ago

I am still doubting what to do with the redefinitions of \leftmark and \rightmark in the current implementation. Leave them as they are now? Is that future proof? Or use \LastMark{2e-left} for '\lastmarkand\FirstMark{2e-right}for\rightmark`? I guess these will be the new definitions in the kernel. And then when the kernel is updated I can leave them out.

I want to keep both fancyhdr and extramarks as much backwards compatible as is reasonable. So that would mean these changes need som run-time tests.

In the new implementation I can leave them out completely, because the definitions in the kernel don't interfere with the new marks then.

FrankMittelbach commented 12 hours ago

I am still doubting what to do with the redefinitions of \leftmark and \rightmark in the current implementation. Leave them as they are now? Is that future proof? Or use \LastMark{2e-left} for '\lastmarkand\FirstMark{2e-right}for\rightmark`? I guess these will be the new definitions in the kernel. And then when the kernel is updated I can leave them out.

Starting with the June release \leftmark and \rightmark will not any longer use the old mark mechanism and from that point onwards you shouldn't touch them, because you would break LaTeX. The issue is a bit how to handle old and new, but that could be done with \IfFormatAtLeastTF if you want to support the old method with old installations (but then they probably have an old extramarks in their distribution and it doesn't matter much either way.

I would probbaly make such a test and depending on the outcome load a frozen version with the old method or a new one based on the new Mark mechanism.