[latex3-commits] [git/LaTeX3-latex3-hyperref] cleanup-patches: add MakeLinkTarget code and docu (9030328)

Ulrike Fischer fischer at troubleshooting-tex.de
Mon May 2 16:58:51 CEST 2022


Repository : https://github.com/latex3/hyperref
On branch  : cleanup-patches
Link       : https://github.com/latex3/hyperref/commit/9030328c3e58fdb329251a2556173250bb8fe1ce

>---------------------------------------------------------------

commit 9030328c3e58fdb329251a2556173250bb8fe1ce
Author: Ulrike Fischer <fischer at troubleshooting-tex.de>
Date:   Mon May 2 16:58:51 2022 +0200

    add MakeLinkTarget code and docu


>---------------------------------------------------------------

9030328c3e58fdb329251a2556173250bb8fe1ce
 ChangeLog.txt           |   5 +-
 build.lua               |   7 +-
 doc/hyperref-doc.tex    | 101 +++++++--
 hyperref-linktarget.dtx | 582 ++++++++++++++++++++++++++++++++++++++++++++++++
 hyperref.dtx            | 127 ++++++-----
 hyperref.ins            |  33 ++-
 manifest.txt            |   9 +-
 7 files changed, 777 insertions(+), 87 deletions(-)

diff --git a/ChangeLog.txt b/ChangeLog.txt
index dc65956..5544edc 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,5 +1,8 @@
 XXXX-XX-XX Ulrike Fischer/David Carlisle
 
+    * added new interface for package authors to create targets for internal
+      links
+    * allow to suppress sectioning patches of hyperref 
     * removed loading of memhfixc: memoir handles that now by itself.
     * removed an old patch for KOMA before 2001
     * removed compability code for pdftex 1.14
@@ -18,7 +21,7 @@ XXXX-XX-XX Ulrike Fischer/David Carlisle
       \ref, \pageref, \Ref, \nameref and \ref*, \pageref*, \Ref*, \nameref*
     * removed older varioref code, a varioref newer than 2019 is now needed.
     * improved support for showkeys.
-    * Removed the contentsline tests, no longer needed as contentsline
+    * Removed the \contentsline tests, no longer needed as \contentsline
       has now four arguments also in latex.
     * \MakeUppercase and \MakeLowercase work now in bookmark if the expl3
     support is detected.
diff --git a/build.lua b/build.lua
index 028c0d1..d337127 100644
--- a/build.lua
+++ b/build.lua
@@ -15,6 +15,7 @@ tdslocations = {
   "doc/latex/hyperref/hyperref-doc.css",
   "doc/latex/hyperref/hyperref-doc.html",
   "doc/latex/hyperref/hyperref-doc.pdf",
+  "doc/latex/hyperref/hyperref-linktarget.pdf",
   "doc/latex/hyperref/hyperref-doc2.html",
   "doc/latex/hyperref/hyperref-doc3.html",
   "doc/latex/hyperref/hyperref-doc4.html",
@@ -115,7 +116,11 @@ end
 
 --excludefiles={"hyperref/hyperref-doc.tex"}
 
-typesetfiles = {"hyperref-doc.tex", "backref.dtx", "hyperref.dtx", "nameref.dtx"}
+typesetfiles = {"hyperref-doc.tex", 
+                "backref.dtx", 
+                "hyperref.dtx", 
+                "nameref.dtx",
+                "hyperref-linktarget.dtx"}
 
 local function type_manual()
   print("Special Typesetting hyperref-doc")
diff --git a/doc/hyperref-doc.tex b/doc/hyperref-doc.tex
index dda8369..eed3c88 100644
--- a/doc/hyperref-doc.tex
+++ b/doc/hyperref-doc.tex
@@ -363,29 +363,6 @@ are naturally interfaces too, they are not explicitly mentioned here again.
 
 This section is work in progress. Suggestions or comments are welcome.
 
-\subsection{Patches and how to suppress them}
-
-Patches to external commands can be avoided alltogether by loading hyperref with the option \texttt{implicit=false}. But is often too drastic. There is a work in progress to classify
-the patches and to offer interfaces to suppress them in a more granular way.
-
-We start with the sectioning commands. 
-
-\begin{itemize}
-\item hyperref patches \cs{@sect}, \cs{@ssect}, \cs{@chapter}, \cs{@schapter},
-\cs{@part}, \cs{@spart}.  
-
-To commands for the starred sections a target for a link is added. To the other commands
-it is added if the sectioning is unnumbered, e.g. because of the \texttt{secnumdepth} setting or in the 
-frontmatter. 
-
-The patch can be suppressed by defining the command \cs{hyper at nopatch@sectioning}. This should normally
-be done only by a class or a package which provides sectioning commands and can add the targets itself.
-Targets have a location on the page and e.g. the section commands should take indents into
-account. Note that the nameref package patches these commands too to add commands to store the title text
-for a label. Check the nameref documentation about a way to suppress these patches. 
-\end{itemize}
-
-
 
 \subsection{Counters}
 Counters play an important part in the code. They are used to create destination names and
@@ -436,6 +413,84 @@ New drivers must provide this commands with similar arguments.
  \hyper at linknamed {action}{link text}                  %Named, only with new generic driver
 \end{verbatim}
 
+\subsection{Creating targets}
+
+Internal links and bookmarks need something they can jump to. In a PDF this is normally called
+a \emph{destination} (and the primitive is therefor called \cs{pdfdest}), in HTML it is more
+common to call this an \emph{anchor} (and the \xpackage{hyperref} uses therefor \cs{hyper at anchor}). 
+History can not be undone but future commands and descriptions will use the generic
+\emph{target} unless the PDF specific destination is meant.
+
+Targets are created automatically when \cs{refstepcounter} is used and in many cases this
+does the right thing and nothing more is needed. 
+But there are exceptions: 
+\begin{itemize}
+\item A needed target can be missing for example
+if a sectioning command doesn't have a number as the starred version is used or due to the 
+setting of \texttt{secnumdepth}. 
+\item The target created by the \cs{refstepcounter} can be in the wrong place.
+\item The target created by the \cs{refstepcounter} can affect spacing.
+\item The target name created by the \cs{refstepcounter} is not usable, e.g. in 
+\cs{bibitem} where you need a target name bases on the bib-key.
+\end{itemize}
+
+Package authors and users can use the following commands to create and manipulate 
+targets. The commands are described in more detail in \texttt{hyperref-linktarget.pdf}.
+
+\begin{verbatim}
+ \MakeLinkTarget
+ \LinkTargetOff
+ \LinkTargetOn
+ \NextLinkTarget
+ \SetLinkTargetFilter
+\end{verbatim}
+
+The first four commands will be defined also in \LaTeX{} directly as no-op and so can be
+used even if \xpackage{hyperref} is not loaded. 
+
+Until \LaTeX{} is updated package authors can also provide these definitions directly:
+
+\begin{verbatim}
+\ProvideDocumentCommand\MakeLinkTarget{sO{}m}{}
+\ProvideDocumentCommand\LinkTargetOn{}{}
+\ProvideDocumentCommand\LinkTargetOff{}{}
+\ProvideDocumentCommand\NextLinkTarget{m}{}
+\end{verbatim}
+
+\subsection{Patches and how to suppress them}
+
+The patches to external commands made by
+\xpackage{hyperref} can be avoided in toto by loading \xpackage{hyperref} 
+with the option \texttt{implicit=false}. 
+But suppressing everything is often too drastic.
+There is a work in progress to classify
+the patches and to offer interfaces to suppress them in a more granular way.
+
+\begin{description}
+\item[sectioning commands]
+\begin{itemize}
+\item hyperref patches \cs{@sect}, \cs{@ssect}, \cs{@chapter}, \cs{@schapter},
+\cs{@part}, \cs{@spart}.
+
+\item It adds to the starred commands a target for a link (with the
+prefix \texttt{chapter*} for chapters and \texttt{section*} otherwise). 
+To the other commands it adds a target for a link
+if the sectioning is unnumbered, e.g. because of the \texttt{secnumdepth} 
+setting or in the front matter.
+
+\item The patch can be suppressed by defining the command \cs{hyper at nopatch@sectioning}. 
+This should normally be done only by a class or a package 
+which provides sectioning commands and adds the targets itself.
+Targets have a location on the page and e.g. the section commands should take indents into
+account. Targets are needed for bookmarks and the table of contents,
+so \cs{@currentHref} should get the correct meaning before 
+\cs{addcontentsline} is used. 
+
+\item Note that the \xpackage{nameref} package patches these commands too 
+to add commands to store the title text in \cs{@currentlabelname}. 
+Check the \xpackage{nameref} documentation about a way to suppress these patches.
+\end{itemize}
+\end{description}
 
 \section{Package options}
 
diff --git a/hyperref-linktarget.dtx b/hyperref-linktarget.dtx
new file mode 100644
index 0000000..4d2a322
--- /dev/null
+++ b/hyperref-linktarget.dtx
@@ -0,0 +1,582 @@
+% \iffalse meta-comment
+%
+%% File: hyperref-linktarget.dtx
+%
+% Copyright (C) 2022-2022 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version.  The latest version
+% of this license is in the file
+%
+%    http://www.latex-project.org/lppl.txt
+%
+% This file is part of the "Hyperref bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+%    https://github.com/latex3/hyperref
+%
+% for those people who are interested.
+%
+%<*driver>
+\RequirePackage{pdfmanagement-testphase}
+\DocumentMetadata{pdfstandard=A-2b}
+\documentclass[full]{l3doc}
+\usepackage{array,booktabs,hyperxmp}
+\hypersetup{pdfauthor=The LaTeX Project,
+  pdftitle=Make link targets (hyperref bundle)}
+\usepackage[skins]{tcolorbox}
+\definecolor{myblue}{RGB}{00,33,99}
+\newtcolorbox{doccomment}[1][]{enhanced,frame hidden,colback=myblue!10,fontupper=\footnotesize,#1}
+%\newtcbox{smalldoccomment}{size=small,on line,enhanced,frame hidden,colback=myblue!10,fontupper=\footnotesize}
+\begin{document}
+  \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+% \title{^^A
+%   Make link targets ^^A
+%   \\
+%   hyperref bundle
+% }
+%
+% \author{^^A
+%  The \LaTeX{} Project\thanks
+%    {^^A
+%      E-mail:
+%        \href{mailto:latex-team at latex-project.org}
+%          {latex-team at latex-project.org}^^A
+%    }^^A
+% }
+%
+% \date{Version XXXX, released XXXX-XX-XX}
+%
+% \maketitle
+% \begin{documentation}
+% \section{Commands to create and adapt targets}
+%  This module provides commands to create targets.
+%  Their goal is to unify and replace
+%  a number of user and internal hyperref commands and to provide a clear
+%  interface for package authors and users.
+% \subsection{The main command}
+% \begin{function}{\MakeLinkTarget}
+% \begin{syntax}
+% \cs{MakeLinkTarget}\oarg{prefix}\Arg{counter}\\
+% \cs{MakeLinkTarget}\oarg{prefix}\{\} \\
+% \cs{MakeLinkTarget}*\Arg{manual target}
+% \end{syntax}
+% \end{function}
+%
+% \cs{MakeLinkTarget} creates a target for an internal link, (called a destination
+% if a PDF is created). In vertical mode the target is created where the command is issued,
+% in horizontal mode it is typically (in a PDF) raised by the current \cs{normalbaselineskip}
+% (similar to the targets created by \cs{refstepcounter}).
+%
+% The arguments allow to control the name of the target/anchor/destination. While technically
+% any unique name (e.g. some number) would work, names related to the actual counter both
+% simplifies the debugging and referencing destinations from external documents. Also \cs{autoref}
+% makes use of the name to identify the type of a label: it splits off the part until the first period and
+% then looks up for a defined name. So if you create a target name \texttt{ABC.CDE.1.2}, \cs{autoref} tries
+% to use \cs{ABCautorefname}.
+%
+% The name is then stored \emph{globally}\footnote{This means that the deprecated \pkg{hyperref}
+% option \texttt{localanchorname} is ignored.} in \cs{@currentHref} and used for example in the
+% next \cs{label}.
+% A target name must be unique across a document. It is up to the users and package
+% authors to ensure this by following the advices given below.
+%
+% \begin{doccomment}
+% A global \cs{@currentHref} means that the target name and
+% the label name can get out of sync: if
+% for example a numbered equation is used between a section and a \cs{label},
+% a reference will show the section number but a link will jump to the equation.
+%
+% \pkg{hyperref} allows to switch to local assignment of \cs{@currentHref}
+% and so to align with the other \cs{label} values with the
+% (so-called experimental) option \texttt{localanchorname}. But while on a document
+% level this can work, it makes it difficult for package authors
+% to add reliable link targets that can be referenced if it is unclear
+% if the assignment is local or global.
+%
+% So the choice was made to set \cs{@currentHref} globally always
+% (and to deprecate \texttt{localanchorname}):
+% This is the default in \pkg{hyperref} since ever and it didn't lead to
+% major problems. It has the advantage to
+% allow to put an anchor in a box and move it around. E.g. in the following
+% example the two \cs{ref} commands
+% reference the section but the second jumps to the top of the rule:
+%
+% \begin{verbatim}
+% \section{An example}\label{sec:title}
+% \newpage \raisebox{3cm}[0pt][0pt]{\phantomsection}%
+% \rule{1cm}{3cm}\label{sec:page2}
+% page two
+% \newpage
+% \ref{sec:title}, \ref{sec:page2}
+% \end{verbatim}
+%
+% \end{doccomment}
+%
+%
+%
+% \subsection*{Target names from counters}
+% \begin{syntax}
+% \cs{MakeLinkTarget}\oarg{prefix}\Arg{counter}
+% \end{syntax}
+%
+% If the mandatory argument is not empty it is interpreted as a \LaTeX{} counter name.
+% The counter is not stepped by the command.
+% If the \meta{counter} doesn't exist, a warning is issued and no target is created.
+%
+% The target name is created as expansion of
+% \texttt{\meta{prefix}.\cs{theH\meta{counter}}} (and so both the prefix
+% and \cs{theH\meta{counter}} should be expandable).
+% The default prefix is the counter name \meta{counter}.
+%
+% For example:
+%
+% \medskip
+% \noindent
+% {\ttfamily
+% \begin{tabular}{@{}l@{}ll}
+% \cs{MakeLinkTarget}\{section\} &$\Rightarrow$ section.\cs{theHsection} & $\Rightarrow$ section.1.1\\
+% \cs{MakeLinkTarget}[sec]\{section\} &$\Rightarrow$ sec.\cs{theHsection}
+% \end{tabular}
+% }
+% \medskip
+%
+% \cs{theH\meta{counter}} must be defined:
+% \cs{MakeLinkTarget} does not try like other \pkg{hyperref} commands to
+% construct the command on-the-fly but warns and creates no
+% target if it doesn't exist.
+% Be aware that if \pkg{hyperref} is used with the option \texttt{implicit=false} it
+% does not predefine and create \cs{theH\meta{counter}} representations
+% so targets could be missing!\footnote{It is planed that \LaTeX{} directly defines
+% the \cs{theH\meta{counter}} for all counters created with \cs{newcounter}.}
+%
+%
+% Typically \cs{theH\meta{counter}} should expand to numbers
+% and periods and make use of parent counters to give a unique representation.
+% The prefix can be a more or less arbitrary string. Spaces are allowed (but not
+% really recommended).
+% A star at the end should be avoided to prevent clashes with
+% the names created when the internal counter is used.
+% The use of non-ASCII chars with pdflatex depends on the \LaTeX{} version: With newer
+% version many of them are safe and with a format 2022-06-01 or newer
+% it should be even possible to use chars in a target name which
+% are undeclared and can't be typeset in the document.
+% But despite the fact that it works, it is recommended to stick to ASCII
+% and to avoid spaces: It is unclear if all PDF viewers and editors can handle
+% them, also they give rather unreadable names in the PDF like |(\360\237\246\206)|
+% and so make debugging harder.
+%
+%
+% Using a special prefix can be useful if the actual counter
+% has an internal name like e.g. \texttt{tcb at cnt@example}.
+% \texttt{\cs{MakeLinkTarget}[tcbexample]\{tcb at cnt@example\}} then gives
+% a nicer looking target name. Care should be taken not to clash
+% with existing counter names and names for \cs{autoref}
+% should be adjusted if needed.
+%
+%
+% \subsection*{Targets using the internal counter}
+% \begin{syntax}
+% \cs{MakeLinkTarget}\oarg{prefix}\{\}
+% \end{syntax}
+%
+% If the mandatory argument is empty a target name based on
+% an internal absolute counter is created.
+% The counter is stepped at every call (and also by other \pkg{hyperref} commands).
+% The prefix is added with a star and a period (see above for
+% the allowed chars). The default prefix is \texttt{page}.
+%
+%
+% \begin{syntax}
+% \begin{tabular}{@{}ll}
+% \cs{MakeLinkTarget}\texttt{\{\}} &$\Rightarrow$ \texttt{page*.1}\\
+% \cs{MakeLinkTarget}\texttt{\{\}} &$\Rightarrow$ \texttt{page*.2}\\
+% \cs{MakeLinkTarget}[section]\texttt{\{\}} &$\Rightarrow$ \texttt{section*.3}\\
+% \end{tabular}
+% \end{syntax}
+%
+% As an example the
+% \pkg{hyperref} command \cs{phantomsection} is equivalent to
+% \texttt{\cs{MakeLinkTarget}[section]\{\}}.
+%
+% \subsection*{Manual target names}
+% \begin{syntax}
+% \cs{MakeLinkTarget}\texttt{*}\Arg{manual target name}
+% \end{syntax}
+%
+% If the starred variant is used a manual target name is created.
+%
+% \texttt{\cs{MakeLinkTarget}*\{destname\}} is roughly equivalent to
+% \texttt{\cs{hypertarget}\{destname\}\{\}} (unlike the
+% latter it also raises the destination in a PDF, and there is no text argument).
+% The target name is expanded, see the remarks about prefixes above regarding
+% the allowed chars.
+%
+% When creating manually targets care should be taken to avoid
+% clashes with automatic target names.
+% As all automatic targets contain at least one period,
+% names without a period are recommended.
+%
+% \begin{doccomment}
+% The second (text) argument of \cs{hypertarget} is only used
+% if the option \texttt{nesting} is set to true---but this option isn't used
+% anywhere (in PDF the idea of a text in the anchor or nesting of anchors
+% makes no sense anyway but also when html is produced e.g. with \texttt{make4ht}
+% it is not used). So probably the option will be deprecated and removed.
+% \end{doccomment}
+%
+% \subsection{Manipulate the next target name}
+%
+% Targets are sometimes created in places where it is difficult to inject
+% a label to retrieve the target name for use e.g. in a bookmark.
+% The next command allows to change the next target name:
+%
+% \begin{function}{\NextLinkTarget}
+% \begin{syntax}
+% \cs{NextLinkTarget}\Arg{manual target}
+% \end{syntax}
+%
+% The command changes the next target name to \meta{manual target}.
+% It does the same as the \cs{hypersetup} key
+% \texttt{next-anchor} and also affects targets created by \cs{refstepcounter}.
+%\end{function}
+%
+% A use case are bookmarks for the table of contents
+% where you know that the heading will create
+% a target:
+%
+% \begin{verbatim}
+% \documentclass{book}
+% \usepackage{bookmark}
+%
+% \begin{document}
+% \bookmark[dest=toc]{Table of Contents}
+% \NextLinkTarget{toc}
+% \tableofcontents
+% \chapter{A}
+% \end{document}
+% \end{verbatim}
+%
+%
+% \subsection*{Hooks}
+%
+% \begin{function}{makelinktarget}
+% The hook \texttt{makelinktarget}\footnote{The hook uses a plain name
+% without reference to the \pkg{hyperref} package in anticipation of the move
+% of this code into the \LaTeX{} kernel.}
+% is executed at the begin of the commands. It is inside a group and
+% so can be used to locally change settings. See below for an example.
+% \end{function}
+%
+%
+% \subsection*{Suppressing the target}
+%
+% \begin{function}{\LinkTargetOn,\LinkTargetOff}
+% \begin{syntax}
+% \cs{LinkTargetOn}\\
+% \cs{LinkTargetOff}
+% \end{syntax}
+% \end{function}
+%
+%
+% This commands allows to switch on and off locally the creation of a target with
+% \cs{MakeLinkTarget}.
+% The switches are also honored by \cs{refstepcounter}\footnote{currently
+% \cs{refstepcounter} doesn't use \cs{MakeLinkTarget} itself but this
+% will probably change.}.
+% This allows to suppress the target
+% from an internal \cs{refstepcounter} and replace it by some manual version
+% by using grouping:
+%
+% \begin{verbatim}
+% \LinkTargetOff %suppress anchor in internal refstepcounter
+% ...
+% \refstepcounter{...}
+% ...
+% {\LinkTargetOn\MakeLinkTarget*{mytarget}} %create manual anchor
+% ...
+% \LinkTargetOn
+% \end{verbatim}
+%
+%
+% \subsection*{Raising the target}
+%
+% In horizontal mode the target is raised by the current value of \cs{normalbaselineskip}.
+%
+% To change this the hook can be used e.g. to double the value everywhere:
+%
+% \begin{verbatim}
+% \AddToHook{cmd/MakeLinkTarget/before}
+%   {\setlength\normalbaselineskip{2\normalbaselineskip}}
+% \leavevmode\MakeLinkTarget{section}
+% \end{verbatim}
+%
+%
+% \subsection{Changing all target names}
+%
+% \begin{function}{\SetLinkTargetFilter}
+% \begin{syntax}
+% \cs{SetLinkTargetFilter}\Arg{filter code using \#1}
+% \end{syntax}
+% \end{function}
+%
+% \pkg{hyperref} provides the command \cs{HyperDestNameFilter} to change all target names.
+% It is applied\footnote{In the backend code, so it depends actually on
+% the driver if it is honored or not}
+% to every target name and is also used in references,
+% but it doesn't change \cs{@currentHref} itself. So after
+%
+% \begin{verbatim}
+% \renewcommand*{\HyperDestNameFilter}[1]{docA-#1}
+% \end{verbatim}
+%
+% you would get in the PDF everywhere the prefix \texttt{docA}
+%
+% \begin{verbatim}
+% %destination names:
+% <<
+% /Names [(docA-Doc-Start) 7 0 R (docA-chapter.1) 8 0 R (docA-page.1) 6 0 R]
+% /Limits [(docA-Doc-Start) (docA-page.1)]
+% >>
+% %link to a chapter
+% /A << /S /GoTo /D (docA-chapter.1) >>
+% %link from the bookmark
+% << /S /GoTo /D (docA-chapter.1) >>
+% \end{verbatim}
+%
+% but the label info in the \texttt{.aux} would show only \texttt{chapter.1}:
+%
+% \begin{verbatim}
+% \newlabel{chap}{{1}{1}{Title}{chapter.1}{}}
+% \end{verbatim}
+%
+% and so \cs{autoref} is still able to extract the counter name.
+%
+% \cs{MakeLinkTarget} uses this filter too: it would break internal link
+% commands if it would ignore it.
+% To stay compatible with future development the filter should not be redefined
+% directly but be set with \cs{SetLinkTargetFilter}.
+% The command can only be used in the preamble.
+%
+% \begin{verbatim}
+% \SetLinkTargetFilter{docA-#1}
+% \end{verbatim}
+% \end{documentation}
+%
+% \begin{implementation}
+% \section{\pkg{maketarget} implementation}
+%    \begin{macrocode}
+%<@@=hyp>
+%<*header>
+\ProvidesExplPackage{maketarget}{2022-04-22}{0.95}
+  {Making targets, destinations and anchors}
+%</header>
+%    \end{macrocode}
+%<package-include>\ExplSyntaxOn
+% \subsection{Variables}
+%    \begin{macrocode}
+%<*package>
+%    \end{macrocode}
+% \begin{macro}{\l_@@_target_create_bool}
+%  This boolean decides if a target is created at all.
+%  (it will replace \cs{@skiphyperref} long term)
+%    \begin{macrocode}
+\bool_new:N \l_@@_target_create_bool
+\bool_set_true:N \l_@@_target_create_bool
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{makelinktarget}
+% This hook is used to adapt for example the raising
+%    \begin{macrocode}
+\hook_new:n {makelinktarget}
+%    \end{macrocode}
+% \end{macro}
+% \subsection{Helper commands}
+% \begin{macro}{\_@@_target_raise:n}
+% We need a command to raise the targets.
+% It is mostly a copy from the hyperref command
+% but we removed the hooks and use \cs{normalbaselineskip}.
+% TODO: The code to save/restore the space factor should
+% be replaced by kernel methods.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_target_raise:n #1
+ {
+   \mode_if_vertical:TF
+    { #1 }
+    {
+     \Hy at SaveSpaceFactor
+     \penalty\@M
+     \smash
+      {
+       \box_move_up:nn
+        { \normalbaselineskip }
+        {
+         \hbox:n
+          {
+           \Hy at RestoreSpaceFactor
+           #1
+           \Hy at SaveSpaceFactor
+          }
+        }
+      }
+     \Hy at RestoreSpaceFactor
+    }
+ }
+%    \end{macrocode}
+% \end{macro}
+% \subsection{Providing the commands}
+% In anticipation of the addition of the main commands to the
+% kernel as no-ops we provide them:
+%    \begin{macrocode}
+\ProvideDocumentCommand\LinkTargetOn{}{}
+\ProvideDocumentCommand\LinkTargetOff{}{}
+\ProvideDocumentCommand\MakeLinkTarget{sO{}m}{}
+\ProvideDocumentCommand\NextLinkTarget{m}{}
+%    \end{macrocode}
+%
+% \subsection{Target on and off switch}
+% \begin{macro}{\LinkTargetOn,\LinkTargetOff}
+%    \begin{macrocode}
+\RenewDocumentCommand\LinkTargetOn {}
+ {
+   \bool_set_true:N \l_@@_target_create_bool
+ }
+
+
+\RenewDocumentCommand\LinkTargetOff {}
+ {
+   \bool_set_false:N \l_@@_target_create_bool
+ }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\MakeLinkTarget}
+% This is the main command. To keep it simple
+% we allow an optional argument also for the manual
+% command but ignore it for now.
+%    \begin{macrocode}
+\RenewDocumentCommand\MakeLinkTarget {s O{} m}
+  {
+    \bool_if:NT \l_@@_target_create_bool
+      {
+        \group_begin:
+        \hook_use:n { makelinktarget }
+        \IfBooleanTF  {#1}
+          {
+            \@@_target_manual:nn {#2}{#3}
+          }
+          {
+            \@@_target_counter:nn {#2}{#3}
+          }
+        \group_end:
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@@_target_manual:nn}
+% This is the code for the manual target name. The prefix is simply ignored.
+%    \begin{macrocode}
+\cs_new_protected:Npn  \@@_target_manual:nn #1 #2 %#1 prefix, #2 name
+  {
+    \tl_gset:Nx \@currentHref {#2}
+    \hook_use:n {__hyp/target/setname}
+    \@onelevel at sanitize\@currentHref
+    \@@_target_raise:n {\hyper at anchorstart{\@currentHref}\hyper at anchorend}
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@@_target_counter:nn}
+% The code for counter related targets must be split into the case
+% where the internal counter is used, and where a user counter is used
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_target_counter:nn #1 #2  %#1 prefix, #2 counter or empty
+  {
+    \tl_if_blank:nTF {#2}
+      {
+        \@@_target_counter_anon:n {#1}
+      }
+      {
+        \@@_target_counter_doc:nn {#1}{#2}
+      }
+  }
+
+%    \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@@_target_counter_anon:n}
+% This creates the target with the internal count.
+% We use the same (tex) count \cs{Hy at linkcounter} than the other
+% hyperref commands.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_target_counter_anon:n #1
+  {
+    \int_gincr:N\Hy at linkcounter
+    \tl_gset:Nx \@currentHref
+      {\tl_if_blank:nTF{#1}{page}{#1}*.\int_use:N\Hy at linkcounter}
+    \hook_use:n {__hyp/target/setname}
+    \@onelevel at sanitize\@currentHref
+    \@@_target_raise:n {\hyper at anchorstart{\@currentHref}\hyper at anchorend}
+  }
+%    \end{macrocode}
+% \end{macro}
+
+% \begin{macro}{\@@_target_counter_doc:nn}
+% And now the target with the user counter. We warn if
+% the counter or the representation doesn't exist
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_target_counter_doc:nn #1 #2
+  {
+    \bool_lazy_and:nnTF { \cs_if_free_p:c {c@#2} } { \cs_if_free_p:c {theH#2} }
+      {
+        \PackageWarning {hyperref}{Counter~'#2'~or~the~representation~'\string\theH#2`\MessageBreak
+        don't~exist.~No~target~created.}{}
+      }
+      {
+        \tl_gset:Nx \@currentHref {\tl_if_blank:nTF{#1}{#2}{#1}.\use:c{theH#2}}
+        \hook_use:n {@@/target/setname}
+        \@onelevel at sanitize\@currentHref
+        \@@_target_raise:n {\hyper at anchorstart{\@currentHref}\hyper at anchorend}
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\NextLinkTarget}
+%  we rely on the internal hook to set the next target name:
+%    \begin{macrocode}
+\RenewDocumentCommand\NextLinkTarget {m}
+  {
+    \hook_gput_next_code:nn {@@/target/setname}
+      {
+        \tl_gset:Nx \@currentHref {#1}
+      }
+  }
+
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\SetLinkTargetFilter}
+% This is an interface to \cs{HyperDestNameFilter}
+%    \begin{macrocode}
+\NewDocumentCommand\SetLinkTargetFilter {m}
+  {
+    \cs_set:Npn \HyperDestNameFilter ##1 {#1}
+  }
+\@onlypreamble \SetLinkTargetFilter
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+%</package>
+%<@@=>.
+%    \end{macrocode}
+%<package-include>\ExplSyntaxOff
+%\end{implementation}
+% \Finale
+\endinput
diff --git a/hyperref.dtx b/hyperref.dtx
index a94d630..bb24ed6 100644
--- a/hyperref.dtx
+++ b/hyperref.dtx
@@ -1,30 +1,30 @@
 % \iffalse
 %% File: hyperref.dtx
-%% Copyright
-%% 1995-2001 Sebastian Rahtz, with portions written by David Carlisle and Heiko Oberdiek,
-%% 2001-2015 Heiko Oberdiek.
-%% 2016-2019 Oberdiek Package Support Group
-%% 2019-2022 LaTeX Project
-%%      https://github.com/latex3/hyperref/issues
-%%
-%% This file is part of the `Hyperref Bundle'.
-%% -------------------------------------------
-%%
-%% This work may be distributed and/or modified under the
-%% conditions of the LaTeX Project Public License, either version 1.3
-%% of this license or (at your option) any later version.
-%% The latest version of this license is in
-%%   http://www.latex-project.org/lppl.txt
-%% and version 1.3 or later is part of all distributions of LaTeX
-%% version 2005/12/01 or later.
-%%
-%% This work has the LPPL maintenance status `maintained'.
-%%
-%% The Current Maintainer of this work is the LaTeX Project.
-%%
-%% The list of all files belonging to the `Hyperref Bundle' is
-%% given in the file `manifest.txt'.
-%%
+% Copyright
+% 1995-2001 Sebastian Rahtz, with portions written by David Carlisle and Heiko Oberdiek,
+% 2001-2015 Heiko Oberdiek.
+% 2016-2019 Oberdiek Package Support Group
+% 2019-2022 LaTeX Project
+%      https://github.com/latex3/hyperref/issues
+%
+% This file is part of the `Hyperref Bundle'.
+% -------------------------------------------
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+%   http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is the LaTeX Project.
+%
+% The list of all files belonging to the `Hyperref Bundle' is
+% given in the file `manifest.txt'.
+%
 %<package|nohyperref|driver|check>\NeedsTeXFormat{LaTeX2e}[2020/10/01]
 %<package>\ProvidesPackage{hyperref}
 %<nohyperref>\ProvidesPackage{nohyperref}
@@ -52,7 +52,7 @@
 %<puvnenc>\ProvidesFile{puvnenc.def}
 %<puarenc>\ProvidesFile{puarenc.def}
 %<psdextra>\ProvidesFile{psdextra.def}
-%<!none>  [2022-02-21 v7.00n %
+%<!none&!packageEnd>  [2022-02-21 v7.00n %
 %<package>  Hypertext links for LaTeX]
 %<nohyperref>  Dummy hyperref (SR)]
 %<driver>  Hyperref documentation driver file]
@@ -10232,8 +10232,9 @@
 \fi
 %</pdfmarkbase|dvipdfm|xetex>
 %    \end{macrocode}
+%
 %    \begin{macrocode}
-%<*package>
+%<*packageEnd>
 %    \end{macrocode}
 %
 %    \begin{macrocode}
@@ -10348,28 +10349,38 @@
 % We do not want the handler for |\refstepcounter| to cut in
 % during the processing of |\item| (we handle that separately),
 % so we provide a bypass conditional.
-% change 2022-04-22: removed test for the slide counter.
+% change 2022-04-22: removed test for the slide counter
+% and for the equation name.
+% change 2022-05-02: added the new boolean set by
+% |\LinkTargetOn/\LinkTargetOff|
+%
 %    \begin{macrocode}
 \newif\if at hyper@item
 \newif\if at skiphyperref
 \@hyper at itemfalse
 \@skiphyperreffalse
+\ExplSyntaxOn
 \def\refstepcounter#1{%
-  \ifHy at pdfstring
-  \else
+  \legacy_if:nF {Hy at pdfstring}
+   {
     \H at refstepcounter{#1}%
-      \if at skiphyperref
-      \else
-        \if at hyper@item
-          \stepcounter{Item}%
-          \hyper at refstepcounter{Item}%
-          \@hyper at itemfalse
-        \else
-          \hyper at refstepcounter{#1}%
-        \fi
-      \fi
-  \fi
+    \bool_lazy_and:nnT
+      { \l__hyp_target_create_bool }
+      { ! \legacy_if_p:n{@skiphyperref} }
+      {
+        \legacy_if:nTF {@hyper at item}
+          {
+            \stepcounter{Item}%
+            \hyper at refstepcounter{Item}%
+            \@hyper at itemfalse
+          }
+          {
+            \hyper at refstepcounter{#1}%
+          }
+      }
+   }
 }
+\ExplSyntaxOff
 \let\Hy at saved@refstepcounter\refstepcounter
 %    \end{macrocode}
 % AMS\LaTeX\ processes all equations twice; we want to make sure
@@ -10532,7 +10543,6 @@
 }
 %    \end{macrocode}
 %    \end{macro}
-%    \begin{macro}{__hyp/target/setname}
 %   We define a hook to allow to overwrite the next destination name.
 %    \begin{macrocode}
 \NewHook{__hyp/target/setname }
@@ -10541,7 +10551,6 @@
        {\Hy at MakeCurrentHref{#1}}%
    }
 %    \end{macrocode}
-% \end{macro}
 %    \begin{macro}{\hyper at makecurrent}
 % Because of Babel mucking around, nullify |\textlatin| when making names.
 % And |\@number| because of babel's lrbabel.def.
@@ -11352,7 +11361,7 @@
 %    \end{macro}
 %
 %    \begin{macrocode}
-%</package>
+%</packageEnd>
 %<*check>
 \checklatex
 \checkcommand\def\@xfootnotenext[#1]{%
@@ -11377,7 +11386,7 @@
   \relax
 }
 %</check>
-%<*package>
+%<*packageEnd>
 %    \end{macrocode}
 %
 % \section{Float captions}\label{captions}
@@ -11488,7 +11497,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-%</package>
+%</packageEnd>
 %<*check>
 \checklatex[1999/06/01 - 2000/06/01]
 \checkcommand\def\caption{%
@@ -11516,7 +11525,7 @@
   \endgroup
 }
 %</check>
-%<*package>
+%<*packageEnd>
 %    \end{macrocode}
 %
 % \section{Bibliographic references}\label{bib}
@@ -11630,7 +11639,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-%</package>
+%</packageEnd>
 %<*check>
 \checklatex
 \checkcommand\def\@lbibitem[#1]#2{%
@@ -11655,7 +11664,7 @@
   \ignorespaces
 }
 %</check>
-%<*package>
+%<*packageEnd>
 %    \end{macrocode}
 %
 % \subsection{Package harvard}
@@ -12035,7 +12044,7 @@
 %    \end{macro}
 %
 %    \begin{macrocode}
-%</package>
+%</packageEnd>
 %<*check>
 \checklatex
 \checkcommand\def\addcontentsline#1#2#3{%
@@ -12043,7 +12052,7 @@
 }
 \checkcommand\def\contentsline#1{\csname l@#1\endcsname}
 %</check>
-%<*package>
+%<*packageEnd>
 %    \end{macrocode}
 %
 % \section{New counters}\label{counters}
@@ -12152,7 +12161,7 @@
 %    A appropriate definition of hyperref's companion counter
 %    (\cmd{\theH...}) is added for correct link names.
 %    \begin{macrocode}
-%</package>
+%</packageEnd>
 %<*check>
 \checkpackage{amsmath}[1999/12/14 - 2000/06/06]
 \checkcommand\newcommand{\numberwithin}[3][\arabic]{%
@@ -12166,7 +12175,7 @@
   }%
 }%
 %</check>
-%<*package>
+%<*packageEnd>
 \@ifpackageloaded{amsmath}{%
   \renewcommand*{\numberwithin}[3][\arabic]{%
     \@ifundefined{c@#2}{\@nocounterr{#2}}{%
@@ -12463,7 +12472,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-%</package>
+%</packageEnd>
 %<*check>
 \checklatex
 \checkcommand\def\@setref#1#2#3{%
@@ -12478,7 +12487,7 @@
   \fi
 }
 %</check>
-%<*package>
+%<*packageEnd>
 %    \end{macrocode}
 %
 % Now some extended referencing. |\ref*| and |\pageref*| are not linked,
@@ -12721,7 +12730,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-%</package>
+%</packageEnd>
 %    \end{macrocode}
 %
 % \section{Configuration files}
@@ -15391,7 +15400,7 @@
 %    is used by writing some clipped text.
 %    \begin{macrocode}
 %<dviwindo>\def\literalps at out#1{\special{ps:#1}}%
-%<package>\providecommand*{\Hy at DistillerDestFix}{}
+%<packageEnd>\providecommand*{\Hy at DistillerDestFix}{}
 %<*pdfmark|dviwindo>
 \def\Hy at DistillerDestFix{%
   \begingroup
@@ -19262,7 +19271,7 @@
 %    \end{macro}
 %    \begin{macrocode}
 %</pdfform>
-%<*package>
+%<*packageEnd>
 %    \end{macrocode}
 %
 % \section{Bookmarks in the PDF file}
@@ -19282,7 +19291,7 @@
   \Hy at MakeCurrentHrefAuto{section*}%
   \Hy at raisedlink{\hyper at anchorstart{\@currentHref}\hyper at anchorend}%
 }
-%</package>
+%</packageEnd>
 %    \end{macrocode}
 %
 % \subsection{Bookmarks}
diff --git a/hyperref.ins b/hyperref.ins
index cc9f61b..bbe33cf 100644
--- a/hyperref.ins
+++ b/hyperref.ins
@@ -55,6 +55,32 @@
 %\askonceonly
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \preamble
+
+Copyright
+1995-2001 Sebastian Rahtz, with portions written by David Carlisle and Heiko Oberdiek,
+2001-2015 Heiko Oberdiek.
+2016-2019 Oberdiek Package Support Group
+2019-2022 LaTeX Project
+     https://github.com/latex3/hyperref/issues
+
+This file is part of the `Hyperref Bundle'.
+-------------------------------------------
+
+This work may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either version 1.3
+of this license or (at your option) any later version.
+The latest version of this license is in
+  http://www.latex-project.org/lppl.txt
+and version 1.3 or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+This work has the LPPL maintenance status `maintained'.
+
+The Current Maintainer of this work is the LaTeX Project.
+
+The list of all files belonging to the `Hyperref Bundle' is
+given in the file `manifest.txt'.
+
 \endpreamble
 
 \generate{%
@@ -65,7 +91,12 @@
   \usedir{tex/latex/hyperref}
   \file{backref.sty}{\from{backref.dtx}{package}}
   \file{nameref.sty}{\from{nameref.dtx}{package}}
-  \file{hyperref.sty}{\from{hyperref.dtx}{package}}
+  \file{hyperref.sty}
+    {
+     \from{hyperref.dtx}{package}
+     \from{hyperref-linktarget.dtx}{package,package-include}
+     \from{hyperref.dtx}{packageEnd}
+    }
   \file{hypertex.def}{\from{hyperref.dtx}{hypertex}}
   \file{pdfmark.def}{\from{hyperref.dtx}{pdfmark,pdfmarkbase,pdfform,outlines}}
   \file{hvtexmrk.def}{\from{hyperref.dtx}{vtexpdfmark}}
diff --git a/manifest.txt b/manifest.txt
index 24a0402..62b3e25 100644
--- a/manifest.txt
+++ b/manifest.txt
@@ -9,8 +9,12 @@ backref.dtx
         Bibliographical back referencing.
 nameref.dtx
         Cross-referencing by name of section.
+hyperref-linktarget.dtx
+        Module with commands to create targets         
+hyperref-patches.dtx
+        outsourced older patches
         
-hyperref.pdf, backref.pdf, nameref.pdf
+hyperref.pdf, backref.pdf, nameref.pdf, hyperref-linktarget.pdf
         Source code documentation.
 
 hyperref.ins
@@ -42,6 +46,7 @@ backref.sty
 nameref.sty
 hyperref.sty
 nohyperref.sty
+hyperref-patches.sty
         LaTeX package files.
 hycheck.tex
 	Test file.
@@ -76,7 +81,7 @@ psdextra.def
 % Directory doc/
 % =============
 
-hyperref-doc.pdf
+hyperref-doc.pdf, hyperref-linktarget.pdf
         Hyperref manual
 hyperref-doc.html, hyperref-doc[2-7].html, hyperref-doc.css,
         HTML version of the manual.





More information about the latex3-commits mailing list.