Menu

#23 pagesize has no effect if typearea is used with standard class

KOMA-Script 3.37
closed
2022-05-16
2022-05-06
U_Fischer
No

The following example gives an A4-pdf instead of the expected A5 in a current texlive. The reason for the misbehaviour can be seen in the \ShowHook: As additions to the begindocument hook are collected "by package" in the new hook system, the \@atdocumenttrue from scrbase is too late.

\documentclass{article}

\usepackage[pagesize=auto,paper=a5]{typearea}
\usepackage{lipsum}
\ShowHook{begindocument}

\begin{document}
\lipsum
\end{document}
-> The hook 'begindocument':
> Code chunks:
>     typearea -> ....
>     scrkbase -> \let \scr@pkgextension \@pkgextension 
>     scrbase -> \let \scr@pkgextension \@pkgextension \@atdocumenttrue 

Discussion

  • Markus Kohm

    Markus Kohm - 2022-05-06

    This is that dammed reordering of \AtBeginDocument code, since \AtBeginDocument is realized using the general hook mechanism. Before this change of the LaTeX kernel the order was the same like the order of the \AtBeginDocument commands. But after the LaTeX kernel change the order is unpredictable. I knew that this breaks things in KOMA-Script but it's hard to find out, where and when. And AFAIK the only solution for it is to define order rules for every package and maybe also to add extra labels to hooks to be able to define more rules than only: execute the hooks of package A before the hooks of package B.

    So for now, I've not only add rules for every KOMA-Script package, that uses \if@atdocument but also have to document, that other package authors who use \if@atdocument also have to add such a rule. Once it was enough to load scrbase before using \if@atdocument in \AtBeginDocument code.

    This is one of these evil cases of: LaTeX kernel changes break packages and it's hard for packages authors to find out, if and how they are related.

     
  • U_Fischer

    U_Fischer - 2022-05-06

    I don't know why there is a \AtBegindocument before scrbase in typearea or why you have to guard the \AtBeginDocument code of typearea with \if@atdocument. But if this is necessary you could use a manual label or the push/pop system or simpler (inside a package) \SetDefaultHookLabel to separate the chunks:

    \documentclass{book}
    \usepackage{lipsum}
    \AddToHook{begindocument}[typearea/beforescrbase]{\def\AAAA{}}
    \usepackage{scrbase}
    \PushDefaultHookLabel {typearea/afterscrbase}
    \AddToHook{begindocument}{\def\BBBB{}}
    \PopDefaultHookLabel
    \ShowHook{begindocument}
    \begin{document}
    
    \end{document}
    
    -> The hook 'begindocument':
    > Code chunks:
    >     typearea/beforescrbase -> \def \AAAA {}
    >     scrbase -> \let \scr@pkgextension \@pkgextension \@atdocumenttrue 
    >     typearea/afterscrbase -> \def \BBBB {}
    > Document-level (top-level) code (executed last):
    >     ---
    > Extra code for next invocation:
    >     ---
    > Rules:
    >     ---
    > Execution order:
    >     typearea/beforescrbase, scrbase, typearea/afterscrbase.
    <recently read> }
    
     
    • Markus Kohm

      Markus Kohm - 2022-05-06

      I don't know why there is a \AtBegindocument before scrbase in typearea.

      This is not the case. The \AtBeginDocument in typearea is after loading scrbase and therefore after the \AtBeginDocument in scrbase. But from LaTeX 2020/10/01 the order of \AtBeginDocument in different packages is not the default order in which LaTeX processes the code.

      In case of KOMA-Script packages, a simple solution could be to add a hook rule as I also wrote in my first reply. But such a rule could be needed for every package, that provides code, that uses \if@atdocument and could be used inside \AtBeginDdocument by another package or class not only for KOMA-Script classes. So in this special case, the better solution could be to add the \@atdocumenttrue to the generic hook begindocument/before already and to document, that \if@atdocumentrue is unspecified from begindocument/before until begindocument. Or maybe I should declare \if@atdocument as deprecated and use per package switches inside KOMA-Script to have a clean solution.

      BTW: pagesize=auto is the initial setting of typearea for several years.

       
  • U_Fischer

    U_Fischer - 2022-05-06
    \AtBeginDocument{%
      \let\scr@pkgextension\@pkgextension
    }
    

    is before \RequirePackage{scrkbase} in my version of typearea and that triggers the chunk.

    Or maybe I should declare \if@atdocument as deprecated

    Well I find the switch a bit curious as it changes to true somewhere in the middle of the begin document hook. For me the document starts only after the hook, as you shouldn't do typesetting here, so from the description I expected it to be false in the hook.

    BTW: pagesize=auto is the initial setting of typearea for several years.

    I know, I only made it explicit for the test.

     
    • Markus Kohm

      Markus Kohm - 2022-05-06

      The \let\scr@pkgextension\@pkgextension is not the problem. The problem is setting and using \if@atdocument.

      Well I find the switch a bit curious as it changes to true somewhere in the middle of the begin document hook. For me the document starts only after the hook, as you shouldn't do typesetting here, so from the description I expected it to be false in the hook.

      With LaTeX before 2020/10/01 \AtBeginDocument was the only available official hook to change \if@atdocument. (Yes, I know etoolbox, but this is not part of the LaTeX kernel and the first version was from about 2007, one year after the first release of scrbase and several years after the first release of typearea).

      And if I would use begindocument/after for changing \if@atdocument to \iftrue now after several years, this would be much more incompatible than moving it to begindocument/before. And it would not help me with my own packages.

       

      Last edit: Markus Kohm 2022-05-06
  • Markus Kohm

    Markus Kohm - 2022-05-06
    • labels: --> kernelchange, scrbase, typearea, hook race
    • status: open --> accepted
    • assigned_to: Markus Kohm
     
  • U_Fischer

    U_Fischer - 2022-05-06

    The \let\scr@pkgextension\@pkgextension is not the problem.

    But the \AtBeginDocument around it is a problem as it starts the typearea chunk. Try it out.

    And if I would use begindocument/after for changing \if@atdocument to \iftrue now after several years, this would be much more incompatible than moving it to begindocument/before. And it would not help me with my own packages.

    I agree that moving to another hook doesn't improve the situation. The switch from false to true would still not be at a not very well defined place. If you want something that is true in the begindocument hook, you could put something into begindocument/before and then test if the hook has been emptied.

    \documentclass{book}
    
    \AddToHook{begindocument/before}{\def\blub{abc}}
    \IfHookEmptyTF{begindocument/before}{\show\true}{\show\false}
    \AddToHook{begindocument}
    {\IfHookEmptyTF{begindocument/before}{\show\true}{}}
    \begin{document}
    aaa
    
    \end{document}
    

    Or you make a feature request that we add something in the kernel hooks. ;-)

     
    • Markus Kohm

      Markus Kohm - 2022-05-06

      But the \AtBeginDocument around it is a problem as it starts the typearea chunk. Try it out.

      Yes, but this is something, that has been changed in the LaTeX kernel not in KOMA-Script.

      If you want something that is true in the begindocument hook, you could put something into begindocument/before and then test if the hook has been emptied.

      What would be the advantage above the fix I've already done and that is at least compatible with usages of \if@atdocument with LaTeX before 2020/10/01?

       

      Related

      Commit: [r3779]

  • Markus Kohm

    Markus Kohm - 2022-05-16
    • status: accepted --> closed
     
  • Markus Kohm

    Markus Kohm - 2022-05-16

    Fixed in [r3779].

     

    Related

    Commit: [r3779]


Log in to post a comment.