texlive[68242] Master/texmf-dist: newpax (11sep23)

commits+karl at tug.org commits+karl at tug.org
Mon Sep 11 23:18:21 CEST 2023


Revision: 68242
          http://tug.org/svn/texlive?view=revision&revision=68242
Author:   karl
Date:     2023-09-11 23:18:21 +0200 (Mon, 11 Sep 2023)
Log Message:
-----------
newpax (11sep23)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/newpax/README.md
    trunk/Master/texmf-dist/doc/latex/newpax/doc-input1.pdf
    trunk/Master/texmf-dist/doc/latex/newpax/doc-input2.pdf
    trunk/Master/texmf-dist/doc/latex/newpax/doc-use-newpax.pdf
    trunk/Master/texmf-dist/doc/latex/newpax/doc-use-pax.pdf
    trunk/Master/texmf-dist/doc/latex/newpax/newpax.pdf
    trunk/Master/texmf-dist/doc/latex/newpax/newpax.tex
    trunk/Master/texmf-dist/source/latex/newpax/newpax.dtx
    trunk/Master/texmf-dist/tex/latex/newpax/newpax.lua
    trunk/Master/texmf-dist/tex/latex/newpax/newpax.sty

Modified: trunk/Master/texmf-dist/doc/latex/newpax/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/newpax/README.md	2023-09-11 21:17:53 UTC (rev 68241)
+++ trunk/Master/texmf-dist/doc/latex/newpax/README.md	2023-09-11 21:18:21 UTC (rev 68242)
@@ -2,14 +2,13 @@
 
 This package allows to insert PDF in a document while preserving
 internal and external links. With lualatex it works in the document
-directly, other engines require to run a compilaton with lualatex or to call
+directly, other engines require to run a compilation with lualatex or to call
 a lua script first.
 
 The package is based on and uses code from [pax](https://ctan.org/pkg/pax) by Heiko Oberdiek.
 
-Packageversion: 0.53 
-Packagedate: 2021-02-26
-Author: Ulrike Fischer
+Packageversion: 0.54 
+Packagedate: 2023-09-11 Author: Ulrike Fischer 
 
 ## License
 The newpax package may be modified and distributed under the terms and conditions of the 

Modified: trunk/Master/texmf-dist/doc/latex/newpax/doc-input1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/newpax/doc-input2.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/newpax/doc-use-newpax.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/newpax/doc-use-pax.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/newpax/newpax.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/newpax/newpax.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/newpax/newpax.tex	2023-09-11 21:17:53 UTC (rev 68241)
+++ trunk/Master/texmf-dist/doc/latex/newpax/newpax.tex	2023-09-11 21:18:21 UTC (rev 68242)
@@ -1,7 +1,7 @@
 % !Mode:: "TeX:UTF-8:Main"
 \makeatletter
-\def\UlrikeFischer at package@version{0.53}
-\def\UlrikeFischer at package@date{2022-09-15}
+\def\UlrikeFischer at package@version{0.54}
+\def\UlrikeFischer at package@date{2023-09-11}
 \makeatother
 \DocumentMetadata{pdfversion=1.7,lang=en-UK, uncompress}
 
@@ -130,6 +130,13 @@
  \item[\PrintKeyName{addannots}] This is a boolean key. It allows to switch on and off the reinserting of the annotations. When set to false  it also suppress warnings in the log if the \file{.newpax} file is not found.
      It is recommended to set it to false for graphics which don't have links.
 
+ \item[\PrintKeyName{dests}] This is a choice key. Currently the values 
+     \texttt{used} (the default) and \texttt{all} are allowed. In the first 
+     case only destinations that are targets of links in the included PDF 
+     will be included, in the second case all destinations (if they are in 
+     the included pages) will be included. The second can be useful if you 
+     want to link to destinations \enquote{from the outside}, see below 
+     section~\ref{sec:outside}.  
 \end{description}
 
 
@@ -179,11 +186,70 @@
 
 \section{Importing annotations}
 
-The \pkg{pax} package from Heiko Oberdiek does the hard work to recalculate the annotation rectangles and to decide which annotation and which destination should be reinserted. It also patches the \cs{includegraphics} command to automate this.
-\pkg{newpax} reuses the core commands of \pkg{pax}. It only adds a number of switches and changes primitive to support more engines and backends.
+The import function has to handle two main problems: 
+\begin{itemize}
+\item Recalculation of coordinates if the imported PDF is scaled or moved
+\item Dropping of annotations and destinations if a PDF is only partially included, e.g. because the graphic is clipped, or because only a selection of pages are included. 
+\end{itemize}    
 
+The \pkg{pax} package from Heiko Oberdiek does here hard work to recalculate the annotation rectangles and to decide which annotation and which destination should be reinserted and patches \cs{includegraphics} command to automate this. \pkg{newpax} mostly reuses the core commands of \pkg{pax} and added only a number of switches and support for more engines and backends.
 
+\section{Internal links}
 
+Internal links (GoTo links in PDF speach) are more complicated than the other link types.
+
+At first they involve two objects: the link annotation and the target of the link (destination in PDF speach). If a PDF is included partially, it is therefore not enough to check if the link area is on the visible pages, one also has to check if the target of the link is there. As such a target can be on a later page the \pkg{pax}/\pkg{newpax} uses the \texttt{.aux} file to record which targets exists and which are required and in a second compilation decides which links and destinations should be reinserted. As an example: if you include from a PDF the table of contents (with links) and a few pages, only the links in the toc pointing to visible sections \emph{and} only the destinations needed for this links will be reinserted.
+
+At second the targets are normally „named destinations“, that means a link 
+annotation points to a string like \texttt{section.1} and the name tree  
+\texttt{/Dests} contains a mapping for this string to an destination object. 
+As names like \texttt{section.1} are used in many PDFs produced by \LaTeX{} 
+they can not simply be reused when reinserting annotations. \pkg{newpax} 
+tries to avoid name clashes by generating names consisting of a prefix with 
+the file name and number or name. So e.g. the \texttt{section.1} destination 
+would be called \texttt{file.newpax at section.1} in the receiving file. If you 
+set up a suffix, e.g. with \texttt{destsuffix=A}, it is appended with an @ 
+symbol, so the result would be \texttt{file.newpax at section.1@A}. If the 
+original destination has not name (this can happen if you include PDFs which 
+haven't been created by TeX), then a number is used, so you get 
+\texttt{file.newpax at 1}. 
+
+
+\subsection{Access from the „outside“}\label{sec:outside}
+
+It is possible to link from the external document to destinations in the 
+included PDF, for example to build a table of contents with links. For this 
+you need  
+
+\begin{itemize}
+\item the included PDF must contain all destinations that you want to use. 
+    That means, \pkg{newpax} won't create destinations out of the blue.
+    
+\item You must ensure that the destinations you need are imported. This 
+    will be the case if they are targets of internal links in the imported 
+    PDF, if not you can force that all destinations of visible pages are 
+    there by using the option \texttt{dests=all}, see above. 
+
+\item You need the names of the destinations. If the imported PDF has been 
+    created with \LaTeX{} you can look in the \texttt{toc} or 
+    \texttt{aux}-file to find names. Then you can setup a filter to link to 
+    the names used by \pkg{newpax} and e.g. load the toc or copy some of 
+    the content lines: 
+    
+    \begin{lstlisting}
+    \newpaxsetup{dests=all}
+    \def\HyperDestNameFilter#1{myinput.newpax@#1}    
+    \input{myinput.toc} %load toc    
+    \includepdf[pages={2-4}]{myinput}
+    \end{lstlisting}
+   
+ \end{itemize}         
+
+
+
+
+
+
 \section{Example input}
 
 \fbox{\includegraphics[scale=0.5,trim=4cm 15cm 8cm 3cm,clip,page=1]{doc-input1}}

Modified: trunk/Master/texmf-dist/source/latex/newpax/newpax.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/newpax/newpax.dtx	2023-09-11 21:17:53 UTC (rev 68241)
+++ trunk/Master/texmf-dist/source/latex/newpax/newpax.dtx	2023-09-11 21:18:21 UTC (rev 68242)
@@ -2,7 +2,7 @@
 %
 % File: newpax.dtx
 % Copyright 2006-2008, 2011, 2012 Heiko Oberdiek (original pax.sty)
-% Copyright (C) 2021, 2022 Ulrike Fischer
+% Copyright (C) 2021--2023 Ulrike Fischer
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -27,14 +27,15 @@
 %    \begin{macrocode}
 %<*package>
 %<@@=newpax>
-\NeedsTeXFormat{LaTeX2e}
+\NeedsTeXFormat{LaTeX2e}[2022-11-01]
 \ProvidesPackage{newpax}%
-  [2022-09-15 v0.53 Annotation support for PDF graphics based on pax.sty adapted by (UF)]%
+  [2023-09-11 v0.54 Annotation support for PDF graphics based on pax.sty adapted by (UF)]%
+%    \end{macrocode}
+% Test if the pdfmanagement is loaded:
+%    \begin{macrocode}
 \ExplSyntaxOn
-\bool_if:nF
-  {
-    \cs_if_exist_p:N \pdfmanagement_if_active_p:
-  }
+\IfDocumentMetadataTF 
+  {} 
   {  %error for now, perhaps warning later.
     \PackageError{newpax}
      {
@@ -43,7 +44,7 @@
      }
      {
        Load~it~with \MessageBreak
-       \string\RequirePackage{pdfmanagement-testphase}\MessageBreak
+       \string\DocumentMetadata{}\MessageBreak
        before~loading~the~class
      }
   }
@@ -50,24 +51,86 @@
 
 \ExplSyntaxOff
 \RequirePackage{graphicx}
-\RequirePackage{ltxcmds}[2011/04/18]
-\RequirePackage{kvsetkeys}[2011/04/07]
-\RequirePackage{kvoptions}[2010/12/23]
-\RequirePackage{auxhook}[2011/03/04]
 \RequirePackage{etoolbox}
-\RequirePackage{xfp}
 
 \ExplSyntaxOn
-%to replace \pdf at strcmp
-\cs_set_eq:NN \newpax at str@if at eq@@@@nnT\str_if_eq:nnT
+%    \end{macrocode}
+% \subsection{Variables}
+% Variables inherited from the pax code use \cs{NEWPAX}
+% as prefix.
+% \begin{variable}{\l_@@_tmpa_box}
+%    \begin{macrocode}
+\box_new:N \l_@@_tmpa_box
+%    \end{macrocode}
+% \end{variable}
 
+% \begin{variable}{ \l_@@_use_attributes_bool}
+% Used by the \texttt{usefileattributes} key.
+%    \begin{macrocode}
 \bool_new:N \l_@@_use_attributes_bool
+%    \end{macrocode}
+% \end{variable}
+% 
+% \begin{variable}{ \l_@@_addannots_bool}
+% Used by the \texttt{addannots} key. 
+%    \begin{macrocode}
 \bool_new:N \l_@@_addannots_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{ \l_@@_dests_all_bool}
+% Used by the \texttt{dests} key. 
+% if true newpax will insert more destinations.
+%    \begin{macrocode}
+\bool_new:N \l_@@_dests_all_bool
+%    \end{macrocode}
+% \end{variable}
 
+% \begin{variable}{ \l_@@_destsuffic_tl}
+% Used by the \texttt{addannots} key. 
+%    \begin{macrocode}
 \tl_new:N   \l_@@_destsuffix_tl
+%    \end{macrocode}
+% \end{variable}
+% 
+% \begin{variable}{\NEWPAX at fileextension}
+% the extension of the generated file, the default it newpax.
+%    \begin{macrocode}
 \tl_new:N \NEWPAX at fileextension
-
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\NEWPAX at Gin@box at opts}
+% this hold the options of a annotation
+%    \begin{macrocode}
+\tl_new:N \NEWPAX at Gin@box at opts
+%    \end{macrocode}
+% \end{variable}
+% 
+% \begin{macro}{\ifNEWPAX at Gin@clip}
+%    \begin{macrocode}
+\newif\ifNEWPAX at Gin@clip
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Variants}
+% 
+% \begin{macro}{\newpax at str@if at eq@@@@nnT}
+% a latex2e variant of \cs{str_if_eq:nnT} to replace 
+% \cs{pdf at strcmp} 
+%    \begin{macrocode}
+\cs_set_eq:NN \newpax at str@if at eq@@@@nnT\str_if_eq:nnT
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
 \cs_generate_variant:Nn \pdfannot_dict_put:nnn {nnx,xnx,xnn}
+\cs_generate_variant:Nn \pdfannot_link_goto_begin:nw {xw}
+\cs_generate_variant:Nn \pdf_destination:nn {xx}
+%    \end{macrocode}
+%
+% \subsection{User setup command}
+%    \begin{macrocode}
 \NewDocumentCommand\newpaxsetup { m }
   {
     \keys_set:nn {newpax}{ #1}
@@ -76,7 +139,7 @@
 \keys_define:nn {newpax}
   {
     usefileattributes .bool_set:N = \l_@@_use_attributes_bool,
-    destsuffix        .tl_set:N   = \l_@@_destsuffix_tl,
+    destsuffix        .code:n     = {\tl_set:Nn \l_@@_destsuffix_tl{@#1}},
     addannots         .bool_set:N = \l_@@_addannots_bool,
     addannots         .default:n  = true,
     addannots         .initial:n  = true,
@@ -83,9 +146,20 @@
     paxextension      .choices:nn =
        {pax,newpax}
        {\tl_set:Nn \NEWPAX at fileextension {#1}},
-    paxextension .initial:n = newpax
+    paxextension .initial:n = newpax,
+    dests             .choice:, 
+    dests/all         .code:n = {\bool_set_true:N \l_@@_dests_all_bool},
+    dests/used        .code:n = {\bool_set_false:N \l_@@_dests_all_bool},
+    dests             .initial:n = used
   }
 
+%    \end{macrocode}
+% \subsection{Helper commands to create the annotations}
+% 
+% \begin{macro}{\@NEWPAX at setattributes@n}
+% This adds or removes attributes from the annot dictionaries.
+% The argument is a link type like URI or Goto.
+%    \begin{macrocode}
 \cs_new_protected:Npn \@NEWPAX at setattributes@n #1 %link type
   {
     \bool_if:NT \l_@@_use_attributes_bool
@@ -133,21 +207,33 @@
       }
   }
 
-
-
-
+%    \end{macrocode}
+% \end{macro}
+% 
+% 
+% \begin{macro}{\@NEWPAX at linkgoto@xnn}
+% this creates a goto link to the destination given in the first argument,
+% and the size given in the second and third argument.
+%    \begin{macrocode}
 \cs_new_protected:Npn \@NEWPAX at linkgoto@xnn #1 #2 #3  %#1 dest #2 width #3 height
   {
     \group_begin:
-      \exp_args:Nx\@NEWPAX at setattributes@n {GoTo}
+      \@NEWPAX at setattributes@n {GoTo}
       \leavevmode
-      \exp_args:Nx\pdfannot_link_goto_begin:nw
+      \pdfannot_link_goto_begin:xw
         { #1 }
         \@NEWPAX at ensurelinkbox@n{\hbox_to_wd:nn {#2}{ { \rule{0pt}{#3} }\hfill}}
       \pdfannot_link_goto_end:
     \group_end:
   }
-
+%    \end{macrocode}
+% \end{macro}
+% 
+% \begin{macro}{\@NEWPAX at link@setaction at nn}
+% This puts the action into the dict 
+% if the annot is a link. \#1 is a type like 
+% URI or Goto, \#2 the actual action.
+%    \begin{macrocode}
 \cs_new_protected:Npn \@NEWPAX at link@setaction at nn #1 #2
  {
     \pdfannot_dict_put:nnn{link/#1}{Subtype}{/Link}
@@ -154,66 +240,88 @@
     \pdfannot_dict_put:nnx{link/#1}{A}
        {<</Type/Action/S/#1 #2>>}
  }
-
-
-
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@NEWPAX at annotboxlink@nnn}
+% This creates an annotation link box. 
+%    \begin{macrocode}
 \cs_new_protected:Npn \@NEWPAX at annotboxlink@nnn #1 #2 #3   %#1 type, #2 width #3 height
   {
     \group_begin:
-      \exp_args:Nx\@NEWPAX at setattributes@n {#1}
+      \@NEWPAX at setattributes@n {#1}
       \leavevmode
       \pdfannot_box:nnnx {#2}{#3}{0pt}
          {\pdfannot_dict_use:n{link/#1}}
     \group_end:
   }
-
+%    \end{macrocode}
+% \end{macro}
+% 
+% \begin{macro}{\@NEWPAX at destination@xx}
+% This creates a destination. The first argument is the 
+% name, the second the placement type (e.g. fit or xyz). 
+%    \begin{macrocode}
 \cs_new_protected:Npn \@NEWPAX at destination@xx #1 #2
   {
-    \exp_args:Nxx \pdf_destination:nn {#1}{#2}
+    \pdf_destination:xx {#1}{#2}
   }
-
-% only defined if hyperref is loaded ...
-\sys_if_engine_xetex:TF
+%    \end{macrocode}
+% \end{macro}
+% 
+%
+% \begin{macro}{\@NEWPAX at ensurelinkbox@n}
+% XeTeX needs in some places a specific box to ensure the size.
+% TODO: check the mailing list for the alternative. 
+%    \begin{macrocode}
+\cs_new_eq:NN \@NEWPAX at ensurelinkbox@n \use:n
+\AddToHook{package/hyperref/after}
   {
-    \cs_set_eq:NN \@NEWPAX at ensurelinkbox@n \XeTeXLinkBox
-  }
+    \sys_if_engine_xetex:T
+      {
+        \cs_set_eq:NN \@NEWPAX at ensurelinkbox@n \XeTeXLinkBox
+      }
+  } 
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Handling graphics commands}
+% We must redefine \cs{includegraphics} to inject the code which
+% reinserts the annotation. This can't be done with hooks as the 
+% standard code splits everything too much.
+% 
+% \begin{macro}{\NEWPAX at ORG@includegraphics}
+%  At first we redefine \cs{includegraphics} to use our new command.
+%    \begin{macrocode}
+\NewCommandCopy\NEWPAX at ORG@includegraphics\includegraphics
+\RenewDocumentCommand\includegraphics{sO{}m}
   {
-    \cs_set_eq:NN \@NEWPAX at ensurelinkbox@n \use:n
+    \IfBooleanTF {#1}
+      {
+        \NEWPAX at includegraphics[clip,#2]{#3} 
+      }
+      {
+        \NEWPAX at includegraphics[#2]{#3} 
+      }
   }
-\ExplSyntaxOff
-% Hook into \includegraphics of graphicx with one optional
-% star, one optional argument with key value pairs and
-% the graphics name
-\let\NEWPAX at ORG@includegraphics\includegraphics
-\def\includegraphics{%
-  \@ifstar{%
-    \@ifnextchar[{%
-      \begingroup
-        \def\x{\endgroup
-           \NEWPAX at includegraphics[clip,%
-        }%
-      \expandafter\x\@gobble
-    }{%
-      \NEWPAX at includegraphics[clip]%
-    }%
-  }{%
-    \@ifnextchar[{%
-      \NEWPAX at includegraphics
-    }{%
-      \NEWPAX at includegraphics[]%
-    }%
-  }%
-}
-
-\ExplSyntaxOn
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\NEWPAX at includegraphics}
+%    \begin{macrocode}
 \def\NEWPAX at includegraphics[#1]#2{%
-  \begingroup
-    \sbox0{\NEWPAX at ORG@includegraphics[{#1}]{#2}}%
-    \edef\NEWPAX at inc@width{\the\wd0}%
-    \edef\NEWPAX at inc@height{\the\dimexpr\dp0+\ht0}%
-    \leavevmode
-    \hbox to \wd0{%
-      \rlap{\copy0}%
+  \group_begin:
+    \hbox_set:Nn \l_@@_tmpa_box {\NEWPAX at ORG@includegraphics[{#1}]{#2}}%
+    \tl_set:Nx \NEWPAX at inc@width  
+      { \dim_eval:n { \box_wd:N \l_@@_tmpa_box } }%
+    \tl_set:Nx \NEWPAX at inc@height 
+      { \dim_eval:n { \box_dp:N \l_@@_tmpa_box + \box_ht:N \l_@@_tmpa_box } }%
+    \mode_leave_vertical:
+    \hbox_to_wd:nn 
+     { \box_wd:N \l_@@_tmpa_box }
+     { 
+      \hbox_overlap_right:n { \box_use:N \l_@@_tmpa_box }
       \bool_if:nT
         { \l_@@_addannots_bool
            &&
@@ -230,32 +338,54 @@
            )
         }
         {
-          \raise-\dp0\hbox
-            {
-              \NEWPAX at AddAnnots{#1}{#2}%
-            }
+          \box_move_down:nn 
+           {\box_dp:N \l_@@_tmpa_box } 
+           {
+             \hbox:n
+               {
+                \NEWPAX at AddAnnots{#1}{#2}%
+               }
+           } 
         }
       \hfill
     }
-  \endgroup
+  \group_end:
 }
+%    \end{macrocode}
+% \end{macro}
+% 
+% \subsection{Handling the newpax file}
+% The following keys were previously defined
+% with kvoptions, the names of the internal commands are kept for now.
+% The keys are used in the optional argument of \cs{includegraphics} 
+% and extend their functions.
+%    \begin{macrocode}
+\keys_define:nn {newpax/Gin}
+ {
+   ,page  .tl_set:N = \NEWPAX at Gin@page
+   ,page  .initial:n = 1
+   ,angle .tl_set:N = \NEWPAX at Gin@angle
+   ,angle .initial:n = 0
+   ,clip  .legacy_if_set:n = NEWPAX at Gin@clip
+   ,viewport .code:n = 
+     {
+       \tl_put_right:Nn\NEWPAX at Gin@box at opts
+         {\NEWPAX at viewport#1\\}
+     }
+   ,trim .code:n = 
+     {
+       \tl_put_right:Nn\NEWPAX at Gin@box at opts
+        {\NEWPAX at trim#1\\}
+     } 
+   ,unknown .code:n = {}     
+ }
 \ExplSyntaxOff
-\SetupKeyvalOptions{family=NEWPAX at Gin,prefix=NEWPAX at Gin@}
-\DeclareStringOption[1]{page}
-\DeclareStringOption[0]{angle}
-\DeclareBoolOption{clip}
-\define at key{NEWPAX at Gin}{viewport}{%
-  \ltx at LocalAppendToMacro\NEWPAX at Gin@box at opts{%
-    \NEWPAX at viewport#1\\%
-  }%
-}
-\define at key{NEWPAX at Gin}{trim}{%
-  \ltx at LocalAppendToMacro\NEWPAX at Gin@box at opts{%
-    \NEWPAX at trim#1\\%
-  }%
-}
-\let\NEWPAX at Gin@box at opts\@empty
 
+%    \end{macrocode}
+%
+% Calculate coordinates 
+% \begin{macro}{\NEWPAX at viewport,\NEWPAX at trim,\NEWPAX at defaultbp,\NEWPAX at def@bp}
+%    \begin{macrocode}
 \def\NEWPAX at viewport#1 #2 #3 #4\\{%
   \NEWPAX at defaultbp\NEWPAX at vllx{#1}%
   \NEWPAX at defaultbp\NEWPAX at vlly{#2}%
@@ -276,7 +406,6 @@
   \edef\NEWPAX at page@urx{\dimexpr\NEWPAX at page@urx-\NEWPAX at turx\relax}%
   \edef\NEWPAX at page@ury{\dimexpr\NEWPAX at page@ury-\NEWPAX at tury\relax}%
 }
-
 \def\NEWPAX at defaultbp#1#2{%
   \afterassignment\NEWPAX at def@bp\dimen@#2bp\relax{#1}{#2}%
 }
@@ -287,12 +416,14 @@
     \edef#2{#3}%
   \fi
 }
-
-% ignore unknown options in family `NEWPAX at Gin'
-\kv at set@family at handler{NEWPAX at Gin}{}
-
+%    \end{macrocode}
+% \end{macro}
+% 
+% \begin{macro}{\NEWPAX at AddAnnots}
+% This command is the main command that reads and parses the newpax file. 
+%    \begin{macrocode}
 \def\NEWPAX at AddAnnots#1#2{%
-  \kvsetkeys{NEWPAX at Gin}{#1}%
+  \SetKeys[newpax/Gin]{#1}%
   \Grot at setangle{\NEWPAX at Gin@angle}%
   % a little careful, is type of angle int or real?
   \loop
@@ -321,7 +452,15 @@
   \catcode`\#=12 \catcode`\%=12
   \InputIfFileExists\NEWPAX at file{}{\typeout{* Missing: \NEWPAX at file}}\endgroup
 }
+%    \end{macrocode}
+% \end{macro}
+% The parsing commands
+% With \cs{NEWPAX at parser}  normally \cs{NEWPAX at cmd@XXX} is called, where
+% XXX is file, pagenum, annot, page or dest.  
+%    \begin{macrocode}
 \def\NEWPAX at parser#1{\NEWPAX at call{cmd}{#1}{}}%
+%    \end{macrocode}
+%    \begin{macrocode}
 \def\NEWPAX at call#1#2#3{%
   \@ifundefined{NEWPAX@#1@#2}\NEWPAX at skip{#3\csname NEWPAX@#1@#2\endcsname}%
 }
@@ -328,6 +467,9 @@
 \def\NEWPAX at skip#1\\{}
 \def\NEWPAX at stop#1\\{}
 
+%    \end{macrocode}
+% The command to handle the page entry.
+%    \begin{macrocode}
 \def\NEWPAX at cmd@page#1#2{%
   \NEWPAX at filter@page{#1}{%
     \NEWPAX at getrect{page}#2\@nil
@@ -377,10 +519,16 @@
   \NEWPAX at call{link}{#2}{%
     \begingroup
     \NEWPAX at getrect{annot}#1\@nil
-    \kvsetkeys{NEWPAX}{#3}%
+    \SetKeys[newpax/key]{#3}%
   }%
   \NEWPAX at skip
 }
+
+%    \end{macrocode}
+
+% Now the main command which inserts annotations. 
+% \begin{macro}{\NEWPAX at pdf@annot}
+%    \begin{macrocode}
 \newif\ifNEWPAX at ok
 \NEWPAX at oktrue
 
@@ -470,7 +618,7 @@
         %additional box for lualatex ...
         \hbox{%
           \@NEWPAX at linkgoto@xnn
-            {NEWPAX@\NEWPAX at file @\NEWPAX at key@DestLabel @\csname l_@@_destsuffix_tl\endcsname}%
+            {\NEWPAX at file @\NEWPAX at DestName}%
             {\NEWPAX at width}%
             {\NEWPAX at height}%
             }%
@@ -486,13 +634,18 @@
   \fi
   \endgroup
 }
-
-
+%    \end{macrocode}
+% \end{macro}
+% 
+% What do they do??
+%    \begin{macrocode}
 \def\NEWPAX at htype@GoToR{file}
 \def\NEWPAX at htype@GoTo{link}
 \def\NEWPAX at htype@Named{link}
 \def\NEWPAX at htype@URI{url}
-
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \ExplSyntaxOn
 \def\NEWPAX at link@URI{%
   \NEWPAX at pdf@annot{%
@@ -516,26 +669,71 @@
     \fi
   }%
 }
-
-% GoTo
-
-\AddLineBeginAux{%
-  \string\providecommand{\string\NEWPAX at DestReq}[2]{}%
-}
-\AddLineBeginAux{%
-  \string\providecommand{\string\NEWPAX at DestProv}[2]{}%
-}
+%    \end{macrocode}
+%
+% Goto links are the most challenging: here it is not enough to create an 
+% link annotation, one also have to ensure that the destination they point to exist 
+% and are correctly created. The destinations can be on previous (or later) 
+% pages that means that one has to use the aux to record what exists and what 
+% is needed.
+%  
+% At first ensure that the commands are defined to avoid errors if newpax is removed
+%    \begin{macrocode}
+\AddToHook{begindocument}
+  {
+   \immediate\write\@mainaux{\string\providecommand{\string\NEWPAX at DestReq}[2]{}}
+   \immediate\write\@mainaux{\string\providecommand{\string\NEWPAX at DestProv}[2]{}}
+  }
+\AddToHook
+  {include/before}
+  {
+   \immediate\write\@partaux{\string\providecommand{\string\NEWPAX at DestReq}[2]{}}
+   \immediate\write\@partaux{\string\providecommand{\string\NEWPAX at DestProv}[2]{}}
+  }
+%    \end{macrocode}
+%
+% After the aux file has been read the commands should do nothing:
+%    \begin{macrocode}
 \AtBeginDocument{%
   \let\NEWPAX at DestReq\@gobbletwo
   \let\NEWPAX at DestProv\@gobbletwo
 }
+%    \end{macrocode}
+
+% \begin{macro}{\NEWPAX at DestReq}
+% This command records the destinations that are required and should be reinserted.
+%    \begin{macrocode}
 \def\NEWPAX at DestReq#1#2{%
   \expandafter\gdef\csname NEWPAX at REQ@#1@#2\endcsname{}%
 }
+%    \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\NEWPAX at DestProv}
+% This records the destinations that are provided.
+%    \begin{macrocode}
 \def\NEWPAX at DestProv#1#2{%
   \expandafter\gdef\csname NEWPAX at PROV@#1@#2\endcsname{}%
 }
+%    \end{macrocode}
+% \end{macro}
 
+% \begin{macro}[EXP]{\NEWPAX at DestName}
+% This command expands either to the number or the name if it exists. 
+%    \begin{macrocode}
+\ExplSyntaxOn
+\cs_new:Npn \NEWPAX at DestName
+  {
+    \tl_if_empty:eTF 
+      { \NEWPAX at key@DestName }
+      { \NEWPAX at key@DestLabel}
+      { \NEWPAX at key@DestName }
+    \l_@@_destsuffix_tl
+  }
+% \cs_set:Npn \NEWPAX at DestName {  \NEWPAX at key@DestLabel }
+%    \end{macrocode}
+% \end{macro}
+%    \begin{macrocode}
 \def\NEWPAX at link@GoTo{%
   \ifnum0<0\NEWPAX at key@DestLabel\relax
     \expandafter\@firstofone
@@ -546,11 +744,11 @@
   {%
     \if at filesw
       \protected at write\@auxout{}{%
-        \string\NEWPAX at DestReq{\NEWPAX at file}{\NEWPAX at key@DestLabel}%
+        \string\NEWPAX at DestReq{\NEWPAX at file}{\NEWPAX at DestName}%
       }%
     \fi
     % Generate link, if destination exists
-    \@ifundefined{NEWPAX at PROV@\NEWPAX at file @\NEWPAX at key@DestLabel}{%
+    \@ifundefined{NEWPAX at PROV@\NEWPAX at file @\NEWPAX at DestName}{%
       \endgroup
     }{%
       \NEWPAX at GoTotrue
@@ -558,21 +756,32 @@
     }%
   }%
 }
-
-% Read destinations
+%    \end{macrocode}
+% This is the command which reads the destination info.
+%    \begin{macrocode}
 \def\NEWPAX at cmd@dest#1#2#3#4{%
+  \def\NEWPAX at key@DestLabel{#2}%
+  \def\NEWPAX at key@DestName{}%
+  \keys_set_groups:nnn {newpax/key} {destinit} {#4}
   \NEWPAX at filter@page{#1}{%
     \if at filesw
       \protected at write\@auxout{}{%
-        \string\NEWPAX at DestProv{\NEWPAX at file}{#2}%
+        \string\NEWPAX at DestProv{\NEWPAX at file}{\NEWPAX at DestName}%
       }%
+    \bool_if:NT\l_@@_dests_all_bool
+     {
+       \protected at write\@auxout{}
+        {
+          \string\NEWPAX at DestReq{\NEWPAX at file}{\NEWPAX at DestName}%
+        }
+     }  
     \fi
-    \@ifundefined{NEWPAX at REQ@\NEWPAX at file @#2}{%
+    \@ifundefined{NEWPAX at REQ@\NEWPAX at file @\NEWPAX at DestName}{%
     }{%
       \begingroup
         \let\NEWPAX at key@DestY\NEWPAX at page@ury
         \let\NEWPAX at key@DestX\NEWPAX at page@llx
-        \kvsetkeys{NEWPAX}{#4}%
+        \keys_set_filter:nnn {newpax/key} {destinit} {#4}
         \let\NEWPAX at dest@llx\NEWPAX at key@DestX
         \let\NEWPAX at dest@urx\NEWPAX at key@DestX
         \let\NEWPAX at dest@lly\NEWPAX at key@DestY
@@ -644,7 +853,8 @@
             \NEWPAX at scale@y\dimexpr\NEWPAX at dest@lly-\NEWPAX at page@lly\relax
           }%
         \fi
-        \edef\NEWPAX at name{NEWPAX@\NEWPAX at file @#2@\csname l_@@_destsuffix_tl\endcsname}%
+        \edef\NEWPAX at name
+          {\NEWPAX at file @\NEWPAX at DestName}%
         \let\NEWPAX at type\@empty
         \newpax at str@if at eq@@@@nnT{#3}{FITR}{\def\NEWPAX at type{xyz}}%too lazy for now for better fitr
         \newpax at str@if at eq@@@@nnT{#3}{XYZ}
@@ -668,33 +878,41 @@
           \kern\NEWPAX at right
           \hbox{\@NEWPAX at destination@xx {\NEWPAX at name}{\NEWPAX at type}}%
           \hss
-        }%
+        }%      
       \endgroup
+%    \end{macrocode}
+% we undefine the REQ-command to avoid that the dest is set again.
+%    \begin{macrocode}
+      \cs_undefine:c{NEWPAX at REQ@\NEWPAX at file @\NEWPAX at DestName}
     }%
     \NEWPAX at skip
   }%
 }
+%    \end{macrocode}
+% These are keys used in the newpax file. The command names are inherited from kvoptions.
+%    \begin{macrocode}
+\keys_define:nn {newpax/key}
+  {
+   ,URI      .tl_set:N = \NEWPAX at key@URI
+   ,Name     .tl_set:N = \NEWPAX at key@Name
+   ,DestName .tl_set:N = \NEWPAX at key@DestName
+   ,DestName .groups:n = {destinit}
+   ,DestPage .tl_set:N = \NEWPAX at key@DestPage
+   ,DestView .tl_set:N = \NEWPAX at key@DestView
+   ,File     .tl_set:N = \NEWPAX at key@File
+   ,C        .tl_set:N = \NEWPAX at key@C
+   ,Border   .tl_set:N = \NEWPAX at key@Border
+   ,BS       .tl_set:N = \NEWPAX at key@BS
+   ,H        .tl_set:N = \NEWPAX at key@H
+   ,DestLabel .tl_set:N = \NEWPAX at key@DestLabel
+   ,DestLabel .groups:n = {destinit}
+   ,DestRect .tl_set:N = \NEWPAX at key@DestRect
+   ,DestZoom .tl_set:N = \NEWPAX at key@DestZoom
+   ,DestX    .code:n = { \NEWPAX at defaultbp\NEWPAX at key@DestX{#1} }
+   ,DestY    .code:n = { \NEWPAX at defaultbp\NEWPAX at key@DestY{#1} }    
+  }
+\ExplSyntaxOff
 
-\SetupKeyvalOptions{family=NEWPAX,prefix=NEWPAX at key@}
-\DeclareStringOption{URI}
-\DeclareStringOption{Name}
-\DeclareStringOption{DestName}
-\DeclareStringOption{DestPage}
-\DeclareStringOption{DestView}
-\DeclareStringOption{File}
-\DeclareStringOption{C}
-\DeclareStringOption{Border}
-\DeclareStringOption{BS}
-\DeclareStringOption{H}
-\DeclareStringOption{DestLabel}
-\DeclareStringOption{DestRect}
-\DeclareStringOption{DestZoom}
-\define at key{NEWPAX}{DestX}{%
-  \NEWPAX at defaultbp\NEWPAX at key@DestX{#1}%
-}
-\define at key{NEWPAX}{DestY}{%
-  \NEWPAX at defaultbp\NEWPAX at key@DestY{#1}%
-}
 %</package>
 %    \end{macrocode}
 %    \begin{macrocode}
@@ -701,8 +919,8 @@
 %<*lua>
 local ProvidesLuaModule = {
     name          = "newpax",
-    version       = "0.53",       --TAGVERSION
-    date          = "2022-09-15", --TAGDATE
+    version       = "0.54",       --TAGVERSION
+    date          = "2023-09-11", --TAGDATE
     description   = "newpax lua code",
     license       = "The LATEX Project Public License 1.3c"
 }
@@ -1096,11 +1314,19 @@
   return a
 end
 
+-- this outputs the key DestLabel with a count
+
 local function outputKV_goto (count)
   local a = strKV_BEG .. constKEY_DEST_LABEL .. strVALUE_BEG .. count .. strVALUE_END .. strKV_END
   return a
 end
 
+-- this outputs the key DestName with a name
+local function outputKV_goto_name (name)
+  local a = strKV_BEG .. constKEY_DEST_NAME .. strVALUE_BEG .. name .. strVALUE_END .. strKV_END
+  return a
+end
+
 local function outputENTRY_dest (destcount,name,pagereftonum,destnamestoref,pdfedoc)
  local pagenum, data = getdestdata(name,pagereftonum,destnamestoref)
  local mediabox = pdfe.getbox(GETPAGE(pdfedoc,pagenum),"MediaBox")
@@ -1120,7 +1346,7 @@
    if data[4] and data[4][2] then
     a = a .. strKV_BEG .. constKEY_DEST_Y .. strVALUE_BEG .. data[4][2] .. strVALUE_END .. strKV_END
    else
-    a = a .. strKV_BEG .. constKEY_DEST_X .. strVALUE_BEG .. mediabox[4] .. strVALUE_END .. strKV_END
+    a = a .. strKV_BEG .. constKEY_DEST_Y .. strVALUE_BEG .. mediabox[4] .. strVALUE_END .. strKV_END
    end
    if data[5] and data[5][2] then
     a = a .. strKV_BEG .. constKEY_DEST_ZOOM .. strVALUE_BEG .. data[5][2] .. strVALUE_END .. strKV_END
@@ -1150,6 +1376,11 @@
    a = a .. data[5][2] .. strRECT_SEP
    a = a .. data[6][2] .. strVALUE_END .. strKV_END
  end
+  -- output also the name. This perhaps need a check if the name exists 
+  -- print("DEBUG TYPE name", TYPE(name))
+  if not (TYPE(name) == "pdfe.array") then    
+   a = a .. strKV_BEG .. constKEY_DEST_NAME .. strVALUE_BEG .. name .. strVALUE_END .. strKV_END
+  end 
  a = a .. strKVS_END .. strENTRY_END
  return a
 end
@@ -1175,6 +1406,7 @@
   -- build from names table:
   local destnamestorefVAR = getdestreferences (docVAR)
   local collected_destinations = {}
+  local useddestnames = {}
   -- output ...
   WRITE(strENTRY_BEG .. "{pax}{0.1l}" .. strENTRY_END)
   WRITE(outputENTRY_file(fileVAR,docVAR))
@@ -1203,6 +1435,7 @@
                annotgoto,pagereftonumVAR,destnamestorefVAR,docVAR))
         else
           local annotaction = GETDICTIONARY(annot,"A")
+          --  print("DEBUG A:",table.serialize(DICTIONARYTOTABLE(annotaction)))
           local annotactiontype =""
           if annotaction then
             annotactiontype = GETNAME(annotaction,"S")
@@ -1216,8 +1449,14 @@
             if annotactiontype == constKEY_URI then
               WRITE ( outputKV_uri(annotaction) )
             elseif annotactiontype =="GoTo" then
+              local desttype, destname, destdetail =  GETFROMDICTIONARY(annotaction,"D")
+              -- print("DEBUG annotaction", desttype, destname, destdetail)
               destcountVAR=destcountVAR + 1
               WRITE ( outputKV_goto (destcountVAR) )
+              -- this needs perhaps a check if destname actually exists.
+              if desttype == 6 then
+                WRITE ( outputKV_goto_name(destname) )
+              end  
             elseif annotactiontype=="GoToR" then
               WRITE ( outputKV_gotor(annotaction) )
             elseif annotactiontype=="Named" then
@@ -1227,6 +1466,10 @@
             WRITE(strENTRY_END) -- end annot data
             if annotactiontype =="GoTo" then
               local type,annotactiongoto,hex = GETFROMDICTIONARY(annotaction,"D")
+               if type==6 then
+               -- record used name 
+               useddestnames[annotactiongoto] = 1
+              end
               table.insert(collected_destinations, outputENTRY_dest(destcountVAR,annotactiongoto,pagereftonumVAR,destnamestorefVAR,docVAR))
             end
           end
@@ -1237,6 +1480,15 @@
   for i=1,#collected_destinations do
    WRITE (collected_destinations[i])
   end
+  -- write out the rest of the destinations.
+  for k,v in pairs (destnamestorefVAR) do
+   -- ignore use dests and page destinations. 
+    i=string.find(k,"page.",1) 
+    if not useddestnames[k] and not i then
+      destcountVAR=destcountVAR + 1
+      WRITE(outputENTRY_dest(destcountVAR,k,pagereftonumVAR,destnamestorefVAR,docVAR))
+    end
+  end  
   io.close(writeVAR)
 end
 

Modified: trunk/Master/texmf-dist/tex/latex/newpax/newpax.lua
===================================================================
--- trunk/Master/texmf-dist/tex/latex/newpax/newpax.lua	2023-09-11 21:17:53 UTC (rev 68241)
+++ trunk/Master/texmf-dist/tex/latex/newpax/newpax.lua	2023-09-11 21:18:21 UTC (rev 68242)
@@ -20,8 +20,8 @@
 --  
 local ProvidesLuaModule = {
     name          = "newpax",
-    version       = "0.53",       --TAGVERSION
-    date          = "2022-09-15", --TAGDATE
+    version       = "0.54",       --TAGVERSION
+    date          = "2023-09-11", --TAGDATE
     description   = "newpax lua code",
     license       = "The LATEX Project Public License 1.3c"
 }
@@ -406,11 +406,19 @@
   return a
 end
 
+-- this outputs the key DestLabel with a count
+
 local function outputKV_goto (count)
   local a = strKV_BEG .. constKEY_DEST_LABEL .. strVALUE_BEG .. count .. strVALUE_END .. strKV_END
   return a
 end
 
+-- this outputs the key DestName with a name
+local function outputKV_goto_name (name)
+  local a = strKV_BEG .. constKEY_DEST_NAME .. strVALUE_BEG .. name .. strVALUE_END .. strKV_END
+  return a
+end
+
 local function outputENTRY_dest (destcount,name,pagereftonum,destnamestoref,pdfedoc)
  local pagenum, data = getdestdata(name,pagereftonum,destnamestoref)
  local mediabox = pdfe.getbox(GETPAGE(pdfedoc,pagenum),"MediaBox")
@@ -430,7 +438,7 @@
    if data[4] and data[4][2] then
     a = a .. strKV_BEG .. constKEY_DEST_Y .. strVALUE_BEG .. data[4][2] .. strVALUE_END .. strKV_END
    else
-    a = a .. strKV_BEG .. constKEY_DEST_X .. strVALUE_BEG .. mediabox[4] .. strVALUE_END .. strKV_END
+    a = a .. strKV_BEG .. constKEY_DEST_Y .. strVALUE_BEG .. mediabox[4] .. strVALUE_END .. strKV_END
    end
    if data[5] and data[5][2] then
     a = a .. strKV_BEG .. constKEY_DEST_ZOOM .. strVALUE_BEG .. data[5][2] .. strVALUE_END .. strKV_END
@@ -460,6 +468,11 @@
    a = a .. data[5][2] .. strRECT_SEP
    a = a .. data[6][2] .. strVALUE_END .. strKV_END
  end
+  -- output also the name. This perhaps need a check if the name exists
+  -- print("DEBUG TYPE name", TYPE(name))
+  if not (TYPE(name) == "pdfe.array") then
+   a = a .. strKV_BEG .. constKEY_DEST_NAME .. strVALUE_BEG .. name .. strVALUE_END .. strKV_END
+  end
  a = a .. strKVS_END .. strENTRY_END
  return a
 end
@@ -480,6 +493,7 @@
   -- build from names table:
   local destnamestorefVAR = getdestreferences (docVAR)
   local collected_destinations = {}
+  local useddestnames = {}
   -- output ...
   WRITE(strENTRY_BEG .. "{pax}{0.1l}" .. strENTRY_END)
   WRITE(outputENTRY_file(fileVAR,docVAR))
@@ -508,6 +522,7 @@
                annotgoto,pagereftonumVAR,destnamestorefVAR,docVAR))
         else
           local annotaction = GETDICTIONARY(annot,"A")
+          --  print("DEBUG A:",table.serialize(DICTIONARYTOTABLE(annotaction)))
           local annotactiontype =""
           if annotaction then
             annotactiontype = GETNAME(annotaction,"S")
@@ -521,8 +536,14 @@
             if annotactiontype == constKEY_URI then
               WRITE ( outputKV_uri(annotaction) )
             elseif annotactiontype =="GoTo" then
+              local desttype, destname, destdetail =  GETFROMDICTIONARY(annotaction,"D")
+              -- print("DEBUG annotaction", desttype, destname, destdetail)
               destcountVAR=destcountVAR + 1
               WRITE ( outputKV_goto (destcountVAR) )
+              -- this needs perhaps a check if destname actually exists.
+              if desttype == 6 then
+                WRITE ( outputKV_goto_name(destname) )
+              end
             elseif annotactiontype=="GoToR" then
               WRITE ( outputKV_gotor(annotaction) )
             elseif annotactiontype=="Named" then
@@ -532,6 +553,10 @@
             WRITE(strENTRY_END) -- end annot data
             if annotactiontype =="GoTo" then
               local type,annotactiongoto,hex = GETFROMDICTIONARY(annotaction,"D")
+               if type==6 then
+               -- record used name
+               useddestnames[annotactiongoto] = 1
+              end
               table.insert(collected_destinations, outputENTRY_dest(destcountVAR,annotactiongoto,pagereftonumVAR,destnamestorefVAR,docVAR))
             end
           end
@@ -542,6 +567,15 @@
   for i=1,#collected_destinations do
    WRITE (collected_destinations[i])
   end
+  -- write out the rest of the destinations.
+  for k,v in pairs (destnamestorefVAR) do
+   -- ignore use dests and page destinations.
+    i=string.find(k,"page.",1)
+    if not useddestnames[k] and not i then
+      destcountVAR=destcountVAR + 1
+      WRITE(outputENTRY_dest(destcountVAR,k,pagereftonumVAR,destnamestorefVAR,docVAR))
+    end
+  end
   io.close(writeVAR)
 end
 

Modified: trunk/Master/texmf-dist/tex/latex/newpax/newpax.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/newpax/newpax.sty	2023-09-11 21:17:53 UTC (rev 68241)
+++ trunk/Master/texmf-dist/tex/latex/newpax/newpax.sty	2023-09-11 21:18:21 UTC (rev 68242)
@@ -18,14 +18,12 @@
 %% This file is part of the "newpax bundle" (The Work in LPPL)
 %% and all files in that bundle must be distributed together.
 %% 
-\NeedsTeXFormat{LaTeX2e}
+\NeedsTeXFormat{LaTeX2e}[2022-11-01]
 \ProvidesPackage{newpax}%
-  [2022-09-15 v0.53 Annotation support for PDF graphics based on pax.sty adapted by (UF)]%
+  [2023-09-11 v0.54 Annotation support for PDF graphics based on pax.sty adapted by (UF)]%
 \ExplSyntaxOn
-\bool_if:nF
-  {
-    \cs_if_exist_p:N \pdfmanagement_if_active_p:
-  }
+\IfDocumentMetadataTF
+  {}
   {  %error for now, perhaps warning later.
     \PackageError{newpax}
      {
@@ -34,7 +32,7 @@
      }
      {
        Load~it~with \MessageBreak
-       \string\RequirePackage{pdfmanagement-testphase}\MessageBreak
+       \string\DocumentMetadata{}\MessageBreak
        before~loading~the~class
      }
   }
@@ -41,23 +39,23 @@
 
 \ExplSyntaxOff
 \RequirePackage{graphicx}
-\RequirePackage{ltxcmds}[2011/04/18]
-\RequirePackage{kvsetkeys}[2011/04/07]
-\RequirePackage{kvoptions}[2010/12/23]
-\RequirePackage{auxhook}[2011/03/04]
 \RequirePackage{etoolbox}
-\RequirePackage{xfp}
 
 \ExplSyntaxOn
-\cs_set_eq:NN \newpax at str@if at eq@@nnT\str_if_eq:nnT
+\box_new:N \l__newpax_tmpa_box
 
 \bool_new:N \l__newpax_use_attributes_bool
 \bool_new:N \l__newpax_addannots_bool
+\bool_new:N \l__newpax_dests_all_bool
 
 \tl_new:N   \l__newpax_destsuffix_tl
 \tl_new:N \NEWPAX at fileextension
-
+\tl_new:N \NEWPAX at Gin@box at opts
+\newif\ifNEWPAX at Gin@clip
+\cs_set_eq:NN \newpax at str@if at eq@@nnT\str_if_eq:nnT
 \cs_generate_variant:Nn \pdfannot_dict_put:nnn {nnx,xnx,xnn}
+\cs_generate_variant:Nn \pdfannot_link_goto_begin:nw {xw}
+\cs_generate_variant:Nn \pdf_destination:nn {xx}
 \NewDocumentCommand\newpaxsetup { m }
   {
     \keys_set:nn {newpax}{ #1}
@@ -66,7 +64,7 @@
 \keys_define:nn {newpax}
   {
     usefileattributes .bool_set:N = \l__newpax_use_attributes_bool,
-    destsuffix        .tl_set:N   = \l__newpax_destsuffix_tl,
+    destsuffix        .code:n     = {\tl_set:Nn \l__newpax_destsuffix_tl{@#1}},
     addannots         .bool_set:N = \l__newpax_addannots_bool,
     addannots         .default:n  = true,
     addannots         .initial:n  = true,
@@ -73,7 +71,11 @@
     paxextension      .choices:nn =
        {pax,newpax}
        {\tl_set:Nn \NEWPAX at fileextension {#1}},
-    paxextension .initial:n = newpax
+    paxextension .initial:n = newpax,
+    dests             .choice:,
+    dests/all         .code:n = {\bool_set_true:N \l__newpax_dests_all_bool},
+    dests/used        .code:n = {\bool_set_false:N \l__newpax_dests_all_bool},
+    dests             .initial:n = used
   }
 
 \cs_new_protected:Npn \@NEWPAX at setattributes@n #1 %link type
@@ -126,15 +128,14 @@
 \cs_new_protected:Npn \@NEWPAX at linkgoto@xnn #1 #2 #3  %#1 dest #2 width #3 height
   {
     \group_begin:
-      \exp_args:Nx\@NEWPAX at setattributes@n {GoTo}
+      \@NEWPAX at setattributes@n {GoTo}
       \leavevmode
-      \exp_args:Nx\pdfannot_link_goto_begin:nw
+      \pdfannot_link_goto_begin:xw
         { #1 }
         \@NEWPAX at ensurelinkbox@n{\hbox_to_wd:nn {#2}{ { \rule{0pt}{#3} }\hfill}}
       \pdfannot_link_goto_end:
     \group_end:
   }
-
 \cs_new_protected:Npn \@NEWPAX at link@setaction at nn #1 #2
  {
     \pdfannot_dict_put:nnn{link/#1}{Subtype}{/Link}
@@ -141,60 +142,50 @@
     \pdfannot_dict_put:nnx{link/#1}{A}
        {<</Type/Action/S/#1 #2>>}
  }
-
 \cs_new_protected:Npn \@NEWPAX at annotboxlink@nnn #1 #2 #3   %#1 type, #2 width #3 height
   {
     \group_begin:
-      \exp_args:Nx\@NEWPAX at setattributes@n {#1}
+      \@NEWPAX at setattributes@n {#1}
       \leavevmode
       \pdfannot_box:nnnx {#2}{#3}{0pt}
          {\pdfannot_dict_use:n{link/#1}}
     \group_end:
   }
-
 \cs_new_protected:Npn \@NEWPAX at destination@xx #1 #2
   {
-    \exp_args:Nxx \pdf_destination:nn {#1}{#2}
+    \pdf_destination:xx {#1}{#2}
   }
-
-\sys_if_engine_xetex:TF
+\cs_new_eq:NN \@NEWPAX at ensurelinkbox@n \use:n
+\AddToHook{package/hyperref/after}
   {
-    \cs_set_eq:NN \@NEWPAX at ensurelinkbox@n \XeTeXLinkBox
+    \sys_if_engine_xetex:T
+      {
+        \cs_set_eq:NN \@NEWPAX at ensurelinkbox@n \XeTeXLinkBox
+      }
   }
+\NewCommandCopy\NEWPAX at ORG@includegraphics\includegraphics
+\RenewDocumentCommand\includegraphics{sO{}m}
   {
-    \cs_set_eq:NN \@NEWPAX at ensurelinkbox@n \use:n
+    \IfBooleanTF {#1}
+      {
+        \NEWPAX at includegraphics[clip,#2]{#3}
+      }
+      {
+        \NEWPAX at includegraphics[#2]{#3}
+      }
   }
-\ExplSyntaxOff
-\let\NEWPAX at ORG@includegraphics\includegraphics
-\def\includegraphics{%
-  \@ifstar{%
-    \@ifnextchar[{%
-      \begingroup
-        \def\x{\endgroup
-           \NEWPAX at includegraphics[clip,%
-        }%
-      \expandafter\x\@gobble
-    }{%
-      \NEWPAX at includegraphics[clip]%
-    }%
-  }{%
-    \@ifnextchar[{%
-      \NEWPAX at includegraphics
-    }{%
-      \NEWPAX at includegraphics[]%
-    }%
-  }%
-}
-
-\ExplSyntaxOn
 \def\NEWPAX at includegraphics[#1]#2{%
-  \begingroup
-    \sbox0{\NEWPAX at ORG@includegraphics[{#1}]{#2}}%
-    \edef\NEWPAX at inc@width{\the\wd0}%
-    \edef\NEWPAX at inc@height{\the\dimexpr\dp0+\ht0}%
-    \leavevmode
-    \hbox to \wd0{%
-      \rlap{\copy0}%
+  \group_begin:
+    \hbox_set:Nn \l__newpax_tmpa_box {\NEWPAX at ORG@includegraphics[{#1}]{#2}}%
+    \tl_set:Nx \NEWPAX at inc@width
+      { \dim_eval:n { \box_wd:N \l__newpax_tmpa_box } }%
+    \tl_set:Nx \NEWPAX at inc@height
+      { \dim_eval:n { \box_dp:N \l__newpax_tmpa_box + \box_ht:N \l__newpax_tmpa_box } }%
+    \mode_leave_vertical:
+    \hbox_to_wd:nn
+     { \box_wd:N \l__newpax_tmpa_box }
+     {
+      \hbox_overlap_right:n { \box_use:N \l__newpax_tmpa_box }
       \bool_if:nT
         { \l__newpax_addannots_bool
            &&
@@ -211,31 +202,39 @@
            )
         }
         {
-          \raise-\dp0\hbox
-            {
-              \NEWPAX at AddAnnots{#1}{#2}%
-            }
+          \box_move_down:nn
+           {\box_dp:N \l__newpax_tmpa_box }
+           {
+             \hbox:n
+               {
+                \NEWPAX at AddAnnots{#1}{#2}%
+               }
+           }
         }
       \hfill
     }
-  \endgroup
+  \group_end:
 }
+\keys_define:nn {newpax/Gin}
+ {
+   ,page  .tl_set:N = \NEWPAX at Gin@page
+   ,page  .initial:n = 1
+   ,angle .tl_set:N = \NEWPAX at Gin@angle
+   ,angle .initial:n = 0
+   ,clip  .legacy_if_set:n = NEWPAX at Gin@clip
+   ,viewport .code:n =
+     {
+       \tl_put_right:Nn\NEWPAX at Gin@box at opts
+         {\NEWPAX at viewport#1\\}
+     }
+   ,trim .code:n =
+     {
+       \tl_put_right:Nn\NEWPAX at Gin@box at opts
+        {\NEWPAX at trim#1\\}
+     }
+   ,unknown .code:n = {}
+ }
 \ExplSyntaxOff
-\SetupKeyvalOptions{family=NEWPAX at Gin,prefix=NEWPAX at Gin@}
-\DeclareStringOption[1]{page}
-\DeclareStringOption[0]{angle}
-\DeclareBoolOption{clip}
-\define at key{NEWPAX at Gin}{viewport}{%
-  \ltx at LocalAppendToMacro\NEWPAX at Gin@box at opts{%
-    \NEWPAX at viewport#1\\%
-  }%
-}
-\define at key{NEWPAX at Gin}{trim}{%
-  \ltx at LocalAppendToMacro\NEWPAX at Gin@box at opts{%
-    \NEWPAX at trim#1\\%
-  }%
-}
-\let\NEWPAX at Gin@box at opts\@empty
 
 \def\NEWPAX at viewport#1 #2 #3 #4\\{%
   \NEWPAX at defaultbp\NEWPAX at vllx{#1}%
@@ -257,7 +256,6 @@
   \edef\NEWPAX at page@urx{\dimexpr\NEWPAX at page@urx-\NEWPAX at turx\relax}%
   \edef\NEWPAX at page@ury{\dimexpr\NEWPAX at page@ury-\NEWPAX at tury\relax}%
 }
-
 \def\NEWPAX at defaultbp#1#2{%
   \afterassignment\NEWPAX at def@bp\dimen@#2bp\relax{#1}{#2}%
 }
@@ -268,11 +266,8 @@
     \edef#2{#3}%
   \fi
 }
-
-\kv at set@family at handler{NEWPAX at Gin}{}
-
 \def\NEWPAX at AddAnnots#1#2{%
-  \kvsetkeys{NEWPAX at Gin}{#1}%
+  \SetKeys[newpax/Gin]{#1}%
   \Grot at setangle{\NEWPAX at Gin@angle}%
   % a little careful, is type of angle int or real?
   \loop
@@ -357,10 +352,12 @@
   \NEWPAX at call{link}{#2}{%
     \begingroup
     \NEWPAX at getrect{annot}#1\@nil
-    \kvsetkeys{NEWPAX}{#3}%
+    \SetKeys[newpax/key]{#3}%
   }%
   \NEWPAX at skip
 }
+
+
 \newif\ifNEWPAX at ok
 \NEWPAX at oktrue
 
@@ -450,7 +447,7 @@
         %additional box for lualatex ...
         \hbox{%
           \@NEWPAX at linkgoto@xnn
-            {NEWPAX@\NEWPAX at file @\NEWPAX at key@DestLabel @\csname l__newpax_destsuffix_tl\endcsname}%
+            {\NEWPAX at file @\NEWPAX at DestName}%
             {\NEWPAX at width}%
             {\NEWPAX at height}%
             }%
@@ -466,12 +463,10 @@
   \fi
   \endgroup
 }
-
 \def\NEWPAX at htype@GoToR{file}
 \def\NEWPAX at htype@GoTo{link}
 \def\NEWPAX at htype@Named{link}
 \def\NEWPAX at htype@URI{url}
-
 \ExplSyntaxOn
 \def\NEWPAX at link@URI{%
   \NEWPAX at pdf@annot{%
@@ -495,25 +490,39 @@
     \fi
   }%
 }
-
-
-\AddLineBeginAux{%
-  \string\providecommand{\string\NEWPAX at DestReq}[2]{}%
-}
-\AddLineBeginAux{%
-  \string\providecommand{\string\NEWPAX at DestProv}[2]{}%
-}
+\AddToHook{begindocument}
+  {
+   \immediate\write\@mainaux{\string\providecommand{\string\NEWPAX at DestReq}[2]{}}
+   \immediate\write\@mainaux{\string\providecommand{\string\NEWPAX at DestProv}[2]{}}
+  }
+\AddToHook
+  {include/before}
+  {
+   \immediate\write\@partaux{\string\providecommand{\string\NEWPAX at DestReq}[2]{}}
+   \immediate\write\@partaux{\string\providecommand{\string\NEWPAX at DestProv}[2]{}}
+  }
 \AtBeginDocument{%
   \let\NEWPAX at DestReq\@gobbletwo
   \let\NEWPAX at DestProv\@gobbletwo
 }
+
 \def\NEWPAX at DestReq#1#2{%
   \expandafter\gdef\csname NEWPAX at REQ@#1@#2\endcsname{}%
 }
+
 \def\NEWPAX at DestProv#1#2{%
   \expandafter\gdef\csname NEWPAX at PROV@#1@#2\endcsname{}%
 }
 
+\ExplSyntaxOn
+\cs_new:Npn \NEWPAX at DestName
+  {
+    \tl_if_empty:eTF
+      { \NEWPAX at key@DestName }
+      { \NEWPAX at key@DestLabel}
+      { \NEWPAX at key@DestName }
+    \l__newpax_destsuffix_tl
+  }
 \def\NEWPAX at link@GoTo{%
   \ifnum0<0\NEWPAX at key@DestLabel\relax
     \expandafter\@firstofone
@@ -524,11 +533,11 @@
   {%
     \if at filesw
       \protected at write\@auxout{}{%
-        \string\NEWPAX at DestReq{\NEWPAX at file}{\NEWPAX at key@DestLabel}%
+        \string\NEWPAX at DestReq{\NEWPAX at file}{\NEWPAX at DestName}%
       }%
     \fi
     % Generate link, if destination exists
-    \@ifundefined{NEWPAX at PROV@\NEWPAX at file @\NEWPAX at key@DestLabel}{%
+    \@ifundefined{NEWPAX at PROV@\NEWPAX at file @\NEWPAX at DestName}{%
       \endgroup
     }{%
       \NEWPAX at GoTotrue
@@ -536,20 +545,29 @@
     }%
   }%
 }
-
 \def\NEWPAX at cmd@dest#1#2#3#4{%
+  \def\NEWPAX at key@DestLabel{#2}%
+  \def\NEWPAX at key@DestName{}%
+  \keys_set_groups:nnn {newpax/key} {destinit} {#4}
   \NEWPAX at filter@page{#1}{%
     \if at filesw
       \protected at write\@auxout{}{%
-        \string\NEWPAX at DestProv{\NEWPAX at file}{#2}%
+        \string\NEWPAX at DestProv{\NEWPAX at file}{\NEWPAX at DestName}%
       }%
+    \bool_if:NT\l__newpax_dests_all_bool
+     {
+       \protected at write\@auxout{}
+        {
+          \string\NEWPAX at DestReq{\NEWPAX at file}{\NEWPAX at DestName}%
+        }
+     }
     \fi
-    \@ifundefined{NEWPAX at REQ@\NEWPAX at file @#2}{%
+    \@ifundefined{NEWPAX at REQ@\NEWPAX at file @\NEWPAX at DestName}{%
     }{%
       \begingroup
         \let\NEWPAX at key@DestY\NEWPAX at page@ury
         \let\NEWPAX at key@DestX\NEWPAX at page@llx
-        \kvsetkeys{NEWPAX}{#4}%
+        \keys_set_filter:nnn {newpax/key} {destinit} {#4}
         \let\NEWPAX at dest@llx\NEWPAX at key@DestX
         \let\NEWPAX at dest@urx\NEWPAX at key@DestX
         \let\NEWPAX at dest@lly\NEWPAX at key@DestY
@@ -621,7 +639,8 @@
             \NEWPAX at scale@y\dimexpr\NEWPAX at dest@lly-\NEWPAX at page@lly\relax
           }%
         \fi
-        \edef\NEWPAX at name{NEWPAX@\NEWPAX at file @#2@\csname l__newpax_destsuffix_tl\endcsname}%
+        \edef\NEWPAX at name
+          {\NEWPAX at file @\NEWPAX at DestName}%
         \let\NEWPAX at type\@empty
         \newpax at str@if at eq@@nnT{#3}{FITR}{\def\NEWPAX at type{xyz}}%too lazy for now for better fitr
         \newpax at str@if at eq@@nnT{#3}{XYZ}
@@ -647,31 +666,33 @@
           \hss
         }%
       \endgroup
+      \cs_undefine:c{NEWPAX at REQ@\NEWPAX at file @\NEWPAX at DestName}
     }%
     \NEWPAX at skip
   }%
 }
+\keys_define:nn {newpax/key}
+  {
+   ,URI      .tl_set:N = \NEWPAX at key@URI
+   ,Name     .tl_set:N = \NEWPAX at key@Name
+   ,DestName .tl_set:N = \NEWPAX at key@DestName
+   ,DestName .groups:n = {destinit}
+   ,DestPage .tl_set:N = \NEWPAX at key@DestPage
+   ,DestView .tl_set:N = \NEWPAX at key@DestView
+   ,File     .tl_set:N = \NEWPAX at key@File
+   ,C        .tl_set:N = \NEWPAX at key@C
+   ,Border   .tl_set:N = \NEWPAX at key@Border
+   ,BS       .tl_set:N = \NEWPAX at key@BS
+   ,H        .tl_set:N = \NEWPAX at key@H
+   ,DestLabel .tl_set:N = \NEWPAX at key@DestLabel
+   ,DestLabel .groups:n = {destinit}
+   ,DestRect .tl_set:N = \NEWPAX at key@DestRect
+   ,DestZoom .tl_set:N = \NEWPAX at key@DestZoom
+   ,DestX    .code:n = { \NEWPAX at defaultbp\NEWPAX at key@DestX{#1} }
+   ,DestY    .code:n = { \NEWPAX at defaultbp\NEWPAX at key@DestY{#1} }
+  }
+\ExplSyntaxOff
 
-\SetupKeyvalOptions{family=NEWPAX,prefix=NEWPAX at key@}
-\DeclareStringOption{URI}
-\DeclareStringOption{Name}
-\DeclareStringOption{DestName}
-\DeclareStringOption{DestPage}
-\DeclareStringOption{DestView}
-\DeclareStringOption{File}
-\DeclareStringOption{C}
-\DeclareStringOption{Border}
-\DeclareStringOption{BS}
-\DeclareStringOption{H}
-\DeclareStringOption{DestLabel}
-\DeclareStringOption{DestRect}
-\DeclareStringOption{DestZoom}
-\define at key{NEWPAX}{DestX}{%
-  \NEWPAX at defaultbp\NEWPAX at key@DestX{#1}%
-}
-\define at key{NEWPAX}{DestY}{%
-  \NEWPAX at defaultbp\NEWPAX at key@DestY{#1}%
-}
 %% 
 %%
 %% End of file `newpax.sty'.



More information about the tex-live-commits mailing list.