% \iffalse meta-comment
%
% File: bookmark.dtx
% Version: 2026-05-21 v1.32
% Info: PDF bookmarks
%
% Copyright (C)
%    2007-2011 Heiko Oberdiek
%    2016-2026 Oberdiek Package Support Group
%    https://github.com/ho-tex/bookmark/issues
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.3c of this license or (at your option) any later
% version. This version of this license is in
%    https://www.latex-project.org/lppl/lppl-1-3c.txt
% and the latest version of this license is in
%    https://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 Maintainers of this work are
% Heiko Oberdiek and the Oberdiek Package Support Group
% https://github.com/ho-tex/bookmark/issues
%
% This work consists of the main source files bookmark.dtx,
% and bookmark.ins and the derived files
%    bookmark.sty, bookmark.pdf, 
%    bkm-dvipdfm.def, bkm-dvips.def,
%    bkm-pdftex.def, bkm-vtex.def,
%    bookmark-example.tex.
%
% Distribution:
%    CTAN:macros/latex/contrib/bookmark/bookmark.dtx
%    CTAN:macros/latex/contrib/bookmark/bookmark.pdf
%
% Unpacking:
%    tex/pdftex/pdflatex bookmark.ins
%
% Documentation:
%    
%         (pdf)latex bookmark.dtx; ...
%         
%    The class ltxdoc loads the configuration file ltxdoc.cfg
%    if available. Here you can specify further options, e.g.
%    use A4 as paper format:
%       \PassOptionsToClass{a4paper}{article}
%
%    Program calls to get the documentation (example):
%       pdflatex bookmark.dtx
%       makeindex -s gind.ist bookmark.idx
%       pdflatex bookmark.dtx
%       makeindex -s gind.ist bookmark.idx
%       pdflatex bookmark.dtx
%
% Installation:
%    TDS:tex/latex/bookmark/bookmark.sty
%    TDS:tex/latex/bookmark/bkm-dvipdfm.def
%    TDS:tex/latex/bookmark/bkm-dvips.def
%    TDS:tex/latex/bookmark/bkm-pdftex.def
%    TDS:tex/latex/bookmark/bkm-vtex.def
%    TDS:doc/latex/bookmark/bookmark.pdf
%    TDS:doc/latex/bookmark/bookmark-example.tex
%    TDS:source/latex/bookmark/bookmark.dtx
%
%<*driver>
\DocumentMetadata{tagging=on}
\documentclass{l3in2edoc}

\DeclareDocElement[printtype=\textit{key},idxtype=key,idxgroup=Keys]{Key}{keydecl}
% they should be robust:
% 
\NewDocumentCommand\xoption{m}{\textsf{#1\DescribeKey[noprint]{#1}}}
\RenewDocumentCommand\hook{m}{\texttt{#1\DescribeHook[noprint]{#1}}}
\newcommand*{\xpackage}[1]{\textsf{#1}}
\newcommand*{\xmodule}[1]{\textsf{#1}}
\newcommand*{\xclass}[1]{\textsf{#1}}
\newcommand*{\xfile}[1]{\texttt{#1}}
\newcommand*{\xext}[1]{\texttt{.#1}}
\newcommand*{\xemail}[1]{%
  \textless\texttt{#1}\textgreater%
}
\newcommand*{\xnewsgroup}[1]{%
  \href{news:#1}{\nolinkurl{#1}}%
}
\newcommand*{\CTANpkg}[1]{%
  \href{http://ctan.org/pkg/#1}{\nolinkurl{CTAN:pkg/#1}}%
}
\newcommand*{\CTAN}[1]{%
  \href{https://ctan.org/tex-archive/#1}{\nolinkurl{CTAN:#1}}%
}
\providecommand*{\docstrip}{\textsf{docstrip}}
\providecommand*{\mikTeX}{\hologo{MiKTeX}}



\newenvironment{Version}[1]
  {\subsection*[toc={[#1]}]{[#1]}\begin{itemize}}
  {\end{itemize}} 
\newenvironment{History}
 {\section{History}\raggedright}{}

\usepackage{etoolbox}
% get rid of index entries from macrocode environments
% 
\ExplSyntaxOn\makeatletter
\bool_new:N\l__BKM_index_macrocode_bool
\DeclareKeys [ BKM / doc ]
 {
  index-macrocode .bool_set:N=\l__BKM_index_macrocode_bool,
  index-macrocode .initial:n=true
 }
\patchcmd \__codedoc_special_index_aux:nnnnnn
  {\__codedoc_index_codeline_hc:nn}
  {
   \bool_if:NTF\l__BKM_index_macrocode_bool
   {\__codedoc_index_codeline_hc:nn}
   {\use_none:nn}
  }
  {}
  {\fail}
\SetKeys[BKM/doc]{index-macrocode=false}  
\ExplSyntaxOff\makeatother


\begin{document}
  \DocInput{bookmark.dtx}%
\end{document}
%</driver>
% \fi
%
%
% \title{The \xpackage{bookmark} package}
% \date{2026-05-21 v1.32}
% \author{Heiko Oberdiek\thanks
% {Please report any issues at \url{https://github.com/ho-tex/bookmark/issues}}}
%
% \maketitle
%
% \begin{abstract}
% This package implements a new bookmark (outline) organization for
% package \xpackage{hyperref}. Bookmark properties such
% as style and color can now be set. Other action types
% are available (URI, GoToR, Named). The bookmarks are
% generated in the first compile run. Package \xpackage{hyperref}
% uses two runs.
% \end{abstract}
%
% \tableofcontents
%
% \section{Documentation}
%
% \subsection{Introduction}
% 
% This package \xpackage{bookmark} tries to provide a more modern
% management for bookmarks:
% \begin{itemize}
% \item The bookmarks are already generated in the first \hologo{TeX} compile run.
% \item The font style and color of the bookmarks can be changed.
% \item More actions than simple GoTo actions are possible.
% \end{itemize}
%
% In the same way as \xpackage{hyperref} \cite{hyperref}
% the bookmarks are generated
% in the order of the bookmark generating macros (\cs{bookmark}).
% A level number is used to define the tree structure of the bookmarks.
% The restrictions are less strict:
% \begin{itemize}
% \item The level values may jump and omit values. A \cs{subsubsection}
%       may follow a \cs{chapter}. This was an error in \xpackage{hyperref},
%       that prints a warning and tries to fix this.
% \item Several bookmarks may point to the same destination.
%       In \xpackage{hyperref} this would mess up the bookmark tree
%       completely, because the algorithm assumes that the destination
%       names are keys (unique).
% \end{itemize}
%
% Note that this package is intended as experimentation platform
% for bookmark management. Feedback is welcome. Also the interfaces
% may change in future versions.
%
% \subsection{Options}
%
% \begin{function}{\bookmarksetup,\bookmarksetupnext,\bookmark}
% Options can be given at four places:
% \begin{enumerate}
% \item \cs{usepackage}|[|\meta{options}|]{bookmark}|\\
%       This is the only place for driver options
%       and option \xoption{atend}.
% \item \cs{bookmarksetup}|{|\meta{options}|}|\\
%       This command is just for setting options.
% \item \cs{bookmarksetupnext}|{|\meta{options}|}|\\
%       The options are stored and called after the
%       options of the next \cs{bookmark} command.
% \item \cs{bookmark}|[|\meta{options}|]{|\meta{title}|}|\\
%       This command sets the bookmark. The option settings remain
%       limited to this bookmark.
% \end{enumerate}
% Exception: Driver options, option \xoption{atend} and
% options \xoption{draft}\slash\xoption{final}
% cannot be changed after the package is loaded.
%\end{function}
%
% \subsubsection{Options \xoption{draft} and \xoption{final}}
%
% If a \LaTeX\ file is compiled several times, then a little
% time can be saved, if option \xoption{draft} is used to
% disable the bookmark stuff of this package. Default is
% \xoption{final}.
% Both options are boolean options, without
% value the value |true| is used. |draft=true| is the same
% as |final=false|.
%
% Options of package \xpackage{bookmark} are local options
% with the exception of driver options. Therefore \xoption{draft}
% or \xoption{final} given as class option is not seen by this
% package. If you want to optimize first \LaTeX\ runs depending
% on a global \xoption{draft}, then package \xpackage{ifdraft}
% and \LaTeX's \cs{PassOptionsToPackage}
% might help in the organization of the preamble, for example:
%\begin{quote}
%\begin{verbatim}
% \documentclass[draft]{article}
% \usepackage{ifdraft}
% \ifdraft{%
%    \PassOptionsToPackage{draft}{bookmark}%
% }{}
%\end{verbatim}
%\end{quote}
%
% \subsubsection{Driver options}
%
% The driver options are now all ignored. 
% If \hologo{VTeX} is detected its driver file will be loaded.
% If not the package calls the \hologo{LaTeX} command \cs{sys_ensure_backend:} 
% to triggers is backend detection and then inspects \cs{c_sys_backend_str}. 
% This means that for \hologo{pdfTeX}, \hologo{LuaLaTeX}, \hologo{XeTeX}
% and \hologo{LaTeX} with dvips you don't need to do anything at all.
% For \hologo{DVIPDFMx} should set the backend globally with one
% of the following options:
% \begin{verbatim}
% \DocumentMetadata{backend=dvipdfmx} %if \DocumentMetadata is used
% \RequirePackage[backend=dvipdfmx]{pdfmanagement}%if the PDF management is used
% \documentclass[dvipdfmx]{article} % otherwise
% \end{verbatim}
% 
% The current versions of the drivers use \LaTeX-hooks and test if the PDF management
% is active and so require a format newer than 2022-06-01.
% 
% \paragraph{Open bookmarks with dvipdfmx.} Older version of
% the package had an option \xoption{dvipdfmx-outline-open}
% to activate code which allows to specify the open
% status of an outline entry.
% The package now assumes that all used dvipdfmx version are current enough to
% understand this code and so activates the code always.
% The option itself will be ignored.
%
%
% \subsubsection{Layout options}
%
% \paragraph{Font options.}
%
% \begin{description}
% \item[\xoption{bold}:] The bookmark is shown with a bold font
%   if the PDF viewer supports this (since PDF 1.4).
% \item[\xoption{italic}:] An italic font is used (since PDF 1.4).
% \end{description}
% Both \xoption{bold} and \xoption{italic} can be used together.
% Using value |false| disables the font option.
%
% \paragraph{Color option.}
%
% Colored bookmarks are a feature of PDF 1.4, they are not supported
% by all PDF viewers.
% \begin{description}
% \item[\xoption{color}:] Here the color can be given as
%   color specification of packages \xpackage{color} or \xpackage{xcolor}.
%   An empty value means that the color property is not set.
%   The recognized values are 
%   \begin{itemize}
%   \item Empty value, no color is set,\\
%         example: |color={}|
%   \item Explicit color specification of color model rgb,\\
%         example for red: |color=[rgb]{1,0,0}|
%   \item Explicit color specification of color model gray,\\
%         example for dark gray: |color=[gray]{0.25}|\\
%   \item Color expressions like |color=red!50!white|. 
%   This requires that either the PDF management or the \xpackage{xcolor} is loaded.       
%   \end{itemize}
% \end{description}
%
% \subsubsection{Action options}
%
% \begin{description}
% \item[\xoption{dest}:] Destination name.
% \item[\xoption{page}:] Page number, first page is 1.
% \item[\xoption{view}:] View specification, examples:\\
%   |view={FitB}|, |view={FitH 842}|, |view={XYZ 0 100 null}|
%   Some view specification parameters expect numbers as parameters
%   with unit bp. They can be given either as plain numbers or
%   as length expressions inside \cs{calc}. Expressions of
%   package \xpackage{calc} are supported if the package is loaded.
%   Otherwise \hologo{eTeX}'s \cs{dimexpr} is used. Example:\\
%   |view={FitH \calc{\paperheight-\topmargin-1in}}|\\
%   |view={XYZ 0 \calc{\paperheight} null}|\\
%   Note that \cs{calc} cannot be used for the third parameter
%   of |XYZ|. This parameter is the zoom value, not a length.
% \item[\xoption{named}:] Named action name:\\
%   |FirstPage|, |LastPage|, |NextPage|, |PrevPage|
% \item[\xoption{gotor}:] Name of the external PDF file.
% \item[\xoption{uri}:] URI specification.
% \item[\xoption{rawaction}:] Raw action specification.
%   Because these specification depends on the driver this option
%   should not be used.
% \end{description}
% The appropriate action for the bookmark is selected by
% analyzing the specified options. The actions
% are distinguished by different sets of options:
% \begin{quote}
% \begin{tabular}{@{}ll@{}}
%   \textbf{Action} & \textbf{Options}\\
%   \hline
%   \textsf{GoTo}: & \xoption{dest}\\
%   \textsf{GoTo}: & \xoption{page} + \xoption{view}\\
%   \textsf{GoToR}: & \xoption{gotor} + \xoption{dest}\\
%   \textsf{GoToR}: & \xoption{gotor} + \xoption{page} + \xoption{view}\\
%   \textsf{Named}: & \xoption{named}\\
%   \textsf{URI}: & \xoption{uri}
% \end{tabular}
% \end{quote}
%
% \paragraph{Missing actions.}
% If the action is missing package \xpackage{bookmark} throws
% an error message. Depending on the driver (\xoption{pdftex},
% \xoption{dvips} and friends) the package detects it quite late
% at the end of the document. Since version 2011/04/21 v1.21
% the package tries printing the line number and file name
% of the corresponding occurrence of \cs{bookmark}.
% However, \hologo{TeX} does provide the line number, but
% unhappily the file name is a secret. The package supports
% some ways to get the file name:
% \begin{itemize}
% \item If \hologo{LuaTeX} (independently from DVI or PDF modes)
%   is running, then its |status.filename| is used automatically.
% \item Package \cs{currfile} \cite{currfile} redefines \hologo{LaTeX}
%    internals to keep track of the file name. If the package
%    is loaded, then its \cs{currfilepath} is detected and used
%    automatically by package \xpackage{bookmark}.
% \item The file name can be set manually by option \xoption{scrfile}
%    in \cs{bookmarksetup} or \cs{bookmark}. But be careful,
%    manual setting disables the previous ways for file name
%    detection. And a wrong or missed file name setting might
%    get you a wrong source location in the error message.
% \end{itemize}
%
% \subsubsection{Level options}
%
% The order of the bookmark entries are defined by the
% appearance order of \cs{bookmark} commands. The tree structure
% is constructed by the property \xoption{level} of the bookmark nodes.
% The values of \xoption{level} are integers. If the level of a
% bookmark entry has a higher value than the previous node, then
% the entry becomes a child of the previous node. The absolute
% value of the difference does not matter.
%
% Package \xpackage{bookmark} remembers the level of the previous
% bookmark entry in a global property `current level'.
%
% The behaviour of the level system can be configured by following
% options:
% \begin{description}
% \item[\xoption{level}:]
%    Sets the level, see the description above. If option \xoption{level}
%    is given without value, then the default behaviour is restored,
%    that the `current level' is used as level value.
%    Since version 2010/10/19 v1.16 package \xpackage{bookmark}
%    also supports names |part|, |section| and other,
%    if the macros \cs{toclevel@part}, \cs{toclevel@section}
%    are defined (done by package \xpackage{hyperref}, see
%    option \xoption{bookmarkdepth}).
% \item[\xoption{rellevel}:]
%    Sets the level relative to the previous level.
%    A positive value means that the bookmark entry become
%    a child of the previous one.
% \item[\xoption{keeplevel}:]
%    Use the level, set by \xoption{level} or \xoption{rellevel},
%    but do not change the global property `current level'.
%    The option can be disabled by setting to |false|.
% \item[\xoption{startatroot}:]
%    At this time the bookmark tree starts at the top level again.
%    The next bookmark entry is not sorted as child to a previous entry.
%    Example scenario: A document uses part. However there are
%    last chapters that should not be put below the last part:
%    \begin{quote}
%\begin{verbatim}
% \documentclass{book}
% [...]
% \begin{document}
%   \part{First part}
%     \chapter{First chapter in first part}
%     [...]
%   \part{Second part}
%     \chapter{First chapter in second part}
%     [...]
%   \bookmarksetup{startatroot}
%   \chapter{Index}% does not belong to second part
% \end{document}
%\end{verbatim}
%    \end{quote}
% \end{description}
%
% \subsubsection{Style definitions}
%
% A style is a group of option settings. It can be defined
% by macro \cs{bookmarkdefinestyle} and is used by option \xoption{style}.
% \begin{function}{\bookmarkdefinestyle} 
% \begin{syntax}
% \cs{bookmarkdefinestyle}\Arg{name}\Arg{key value list}
% \end{syntax}
% The \meta{key value list} of option settings is assigned the
% style \meta{name}.
% \end{function}
%
% \begin{description}
% \item[\xoption{style}:]
%   The value of option \xoption{style} is the name of a previously
%   defined style. Its option settings are now executed.
%   The options may include option \xoption{style}.
%   Endless recursion by calling the same style recursively
%   is prevented and throws an error.
% \end{description}
%
% \subsubsection{Hook support}
%
% A hook is called right after the processing the optional options
% of macro \cs{bookmark}.
% \begin{description}
% \item[\xoption{addtohook}:]
%   Code, given as value to this option is added to the hook.
% \end{description}
%
% \begin{function}{\bookmarkget}
% \begin{syntax}
% \cs{bookmarkget}\Arg{option}
% \end{syntax}
% \end{function}
% 
% Macro \cs{bookmarkget} extracts the value of the latest option
% setting of option \meta{option}. In case of boolean options number
% one is returned, if the boolean option is enabled, otherwise the
% result is zero.
% The resulting numbers can directly be used in \cs{ifnum} or \cs{ifcase}.
% If you want to have the digits \texttt{0} and \texttt{1}, then
% prefix \cs{bookmarkget} with \cs{number}.
% Macro \cs{bookmarkget} is expandable.
% In case of
% unsupported options an empty string is returned.
% Supported boolean options are
% \begin{quote}
%   \xoption{bold},
%   \xoption{italic},
%   \xoption{open}
% \end{quote}
% Other supported options:
% \begin{quote}
%   \xoption{depth},
%   \xoption{dest},
%   \xoption{color},
%   \xoption{gotor},
%   \xoption{level},
%   \xoption{named},
%   \xoption{openlevel},
%   \xoption{page},
%   \xoption{rawaction},
%   \xoption{uri},
%   \xoption{view},
% \end{quote}
% Additionally the following key is available:
% \begin{quote}
%   \xoption{text}
% \end{quote}
% It returns the text of the outline entry.
%
% \paragraph{Option setting.}
% Inside the hook an option can be set using \cs{bookmarksetup}.
%
% \subsection{Compatibility with \xpackage{hyperref}}
%
% Package \xpackage{bookmark} automatically disables
% \xpackage{hyperref}'s bookmarks. However the package
% uses some of the code of \xpackage{hyperref}. For example,
% the package redefines the hook \cs{Hy@writebookmark} that
% \xpackage{hyperref} inserts in \cs{addcontentsline} and
% other commands. Therefore
% \xpackage{hyperref}'s bookmarks should not be disabled.
%
% Package \xpackage{bookmark} uses \xpackage{hyperref}'s \cs{pdfstringdef}
% and does not provide a replacement.
%
% Some options of \xpackage{hyperref} are also implemented
% in package \xpackage{bookmark}:
% \begin{quote}
% \begin{tabular}{@{}ll@{}}
%   \xpackage{hyperref} & \xpackage{bookmark}\\
%   \hline
%   \xoption{bookmarksdepth} & \xoption{depth}\\
%   \xoption{bookmarksopen} & \xoption{open}\\
%   \xoption{bookmarksopenlevel} & \xoption{openlevel}\\
%   \xoption{bookmarksnumbered} & \xoption{numbered}\\
% \end{tabular}
% \end{quote}
%
% The following commands are also available:
% \begin{function}{\pdfbookmark,\currentpdfbookmark,\subpdfbookmark,\belowpdfbookmark}
% \begin{syntax}
%   \cs{pdfbookmark}\oarg{level}\Arg{text}\Arg{name}\\
%   \cs{currentpdfbookmark}\Arg{text}\Arg{name}\\
%   \cs{subpdfbookmark}\Arg{text}\Arg{name}\\
%   \cs{belowpdfbookmark}\Arg{text}\Arg{name}
% \end{syntax}
% They are documented in the hyperref documentation.
% \end{function}
%
% \subsection{Adding bookmarks at the end}
%
% Package option \xoption{atend} enables the following macro:
% \begin{function}{\BookmarkAtEnd}
% \begin{syntax}
% \cs{BookmarkAtEnd}\Arg{stuff}
% \end{syntax}
% \end{function}
% Macro \cs{BookmarkAtEnd} puts \meta{stuff} at the end
% of the document. \meta{stuff} means bookmark commands.
% Example:
% \begin{quote}
%\begin{verbatim}
% \usepackage[atend]{bookmark}
% \BookmarkAtEnd{%
%   \bookmarksetup{startatroot}%
%   \bookmark[named=LastPage, level=0]{Last page}%
% }
%\end{verbatim}
% \end{quote}
%
% Alternatively, option \xoption{startatroot} can be given
% in \cs{bookmark}:
% \begin{quote}
%\begin{verbatim}
% \BookmarkAtEnd{%
%   \bookmark[
%     startatroot,
%     named=LastPage,
%     level=0,
%   ]{Last page}%
% }
%\end{verbatim}
% \end{quote}
%
% \paragraph{Remarks.}
% \begin{itemize}
% \item
%   \cs{BookmarkAtEnd} hides the fact that the method for
%   adding bookmarks at the end of the document depends
%   on the driver.
%
%   The driver \xoption{pdftex} (used by \hologo{pdfLaTeX} and \hologo{LuaLaTeX}
%   uses the hook \hook{enddocument/afterlastpage} 
%    
%   The implementation of the other drivers
%   (\xoption{dvipdfm}, \xoption{xetex}, \xoption{vtex}, \xoption{dvips})
%   depends on
%   \cs{special} that does not have an effect after the last
%   page. In this case the hook \hook{shipout/lastpage} is used.
%   Two \hologo{LaTeX} runs are necessary at least, because
%   the last page is detected by a reference.
%   
% \item
%   The time of expansion of the argument of \cs{BookmarkAtEnd}
%   is not specified. This can happen immediately or at the end
%   of the document.
% \end{itemize}
%
% \subsection{Structure destinations}
% If tagging is activated with 
% \begin{verbatim}
% \DocumentMetadata{tagging=on} 
% \end{verbatim}
% the outlines will also use structure destinations, these are destination
% bound not to a page but to a structure. This works only with \hologo{pdfLaTeX}, \hologo{LuaLaTeX} and
% \hologo{XeLaTeX}. 
% 
% 
% \subsection{Limitations/ToDos}
%
% \begin{itemize}
% \item Support for missing actions (Launch, \dots).
% \item Better design for \xpackage{hyperref}'s option
%       \xoption{bookmarkstype}.
% \end{itemize}
%
% \section{Example}
%
%    \begin{macrocode}
%<*example>
%    \end{macrocode}
%    \begin{macrocode}
\documentclass{article}
\usepackage{xcolor}[2007/01/21]
\usepackage{hyperref}
\usepackage[
  open,
  openlevel=2,
  atend
]{bookmark}[2019/12/03]

\bookmarksetup{color=blue}

\BookmarkAtEnd{%
  \bookmarksetup{startatroot}%
  \bookmark[named=LastPage, level=0]{End/Last page}%
  \bookmark[named=FirstPage, level=1]{First page}%
}

\begin{document}
\section{First section}
\subsection{Subsection A}
\begin{figure}
  \hypertarget{fig}{}%
  A figure.
\end{figure}
\bookmark[
  rellevel=1,
  keeplevel,
  dest=fig
]{A figure}
\subsection{Subsection B}
\subsubsection{Subsubsection C}
\subsection{Umlauts: \"A\"O\"U\"a\"o\"u\ss}
\newpage
\bookmarksetup{
  bold,
  color=[rgb]{1,0,0}
}
\section{Very important section}
\bookmarksetup{
  italic,
  bold=false,
  color=blue
}
\subsection{Italic section}
\bookmarksetup{
  italic=false
}
\part{Misc}
\section{Diverse}
\subsubsection{Subsubsection, omitting subsection}
\bookmarksetup{
  startatroot
}
\section{Last section outside part}
\subsection{Subsection}
\bookmarksetup{
  color={}
}
\begingroup
  \bookmarksetup{level=0, color=green!80!black}
  \bookmark[named=FirstPage]{First page}
  \bookmark[named=LastPage]{Last page}
  \bookmark[named=PrevPage]{Previous page}
  \bookmark[named=NextPage]{Next page}
\endgroup
\bookmark[
  page=2,
  view=FitH 800
]{Page 2, FitH 800}
\bookmark[
  page=2,
  view=FitBH \calc{\paperheight-\topmargin-1in-\headheight-\headsep}
]{Page 2, FitBH top of text body}
\bookmark[
  uri={http://www.dante.de/},
  color=magenta
]{Dante homepage}
\bookmark[
  gotor={t.pdf},
  page=1,
  view={XYZ 0 1000 null},
  color=cyan!75!black
]{File t.pdf}
\bookmark[named=FirstPage]{First page}
\bookmark[rellevel=1, named=LastPage]{Last page (rellevel=1)}
\bookmark[named=PrevPage]{Previous page}
\bookmark[level=0, named=FirstPage]{First page (level=0)}
\bookmark[
  rellevel=1,
  keeplevel,
  named=LastPage
]{Last page (rellevel=1, keeplevel)}
\bookmark[named=PrevPage]{Previous page}
\end{document}
%    \end{macrocode}
%    \begin{macrocode}
%</example>
%    \end{macrocode}
%
% \StopEventually{
% }
%
% \section{Implementation}
% \DoNotIndex{%
%  \",
%  \(,
%  \),
%  \|,
%  \\,
%  \0,
%  \1,
%  \2,
%  \3,
%  \number
%  }
% \subsection{Package}
%
%    \begin{macrocode}
%<*package>
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{bookmark}%
  [2026-05-21 v1.32 PDF bookmarks (HO)]%
%    \end{macrocode}
%
% \subsubsection{Requirements}
%
% \paragraph{\hologo{eTeX}.}
%
%    \begin{macro}[module=BKM]{\BKM@CalcExpr}
%    \begin{macrocode}
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname numexpr\endcsname\relax
  \def\BKM@CalcExpr#1#2#3#4{%
    \begingroup
      \count@=#2\relax
      \advance\count@ by#3#4\relax
      \edef\x{\endgroup
        \def\noexpand#1{\the\count@}%
      }%
    \x
  }%
\else
  \def\BKM@CalcExpr#1#2#3#4{%
    \edef#1{%
      \the\numexpr#2#3#4\relax
    }%
  }%
\fi
%    \end{macrocode}
%    \end{macro}
%
% \paragraph{Escape features of \hologo{pdfTeX}.}
%
%    \begin{macro}[module=BKM]{\BKM@EscapeName}
%    \begin{macrocode}
\def\BKM@EscapeName#1{%
  \ifx#1\@empty
  \else
    \EdefEscapeName#1#1%
  \fi
}%
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@EscapeString}
%    \begin{macrocode}
\def\BKM@EscapeString#1{%
  \ifx#1\@empty
  \else
    \EdefEscapeString#1#1%
  \fi
}%
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@EscapeHex}
%    \begin{macrocode}
\def\BKM@EscapeHex#1{%
  \ifx#1\@empty
  \else
    \EdefEscapeHex#1#1%
  \fi
}%
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@UnescapeHex}
%    \begin{macrocode}
\def\BKM@UnescapeHex#1{%
  \EdefUnescapeHex#1#1%
}%
%    \end{macrocode}
%    \end{macro}
%
% \paragraph{Some helper commands}
% Replaces some commands from ltxcmds:
% 
% \begin{macro}[module=BKM]{\BKM@ReturnAfterFi}
% \begin{macro}[module=BKM]{\BKM@space}
% \begin{macro}[module=BKM]{\BKM@GlobalAppendToMacro}
% \begin{macro}[module=BKM]{\BKM@LocalAppendToMacro}
%    \begin{macrocode}
\ExplSyntaxOn
\let\BKM@LocalAppendToMacro\tl_put_right:Nn
\let\BKM@GlobalAppendToMacro\tl_gput_right:Nn
\ExplSyntaxOff 
\def\BKM@space{ }
\long\def\BKM@ReturnAfterFi#1\fi{\fi#1}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% 
% \paragraph{Packages.}
%
% Don't load packages loaded by \xpackage{hyperref}
%    \begin{macrocode}
\RequirePackage{hyperref}[2010/06/18]
%    \end{macrocode}
%
% \subsubsection{Package options}
%
%    \begin{macrocode}
%\DeclareLocalOptions{%
%  atend,%
%  bold,%
%  color,%
%  depth,%
%  dest,%
%  draft,%
%  final,%
%  gotor,%
%  italic,%
%  keeplevel,%
%  level,%
%  named,%
%  numbered,%
%  open,%
%  openlevel,%
%  page,%
%  rawaction,%
%  rellevel,%
%  srcfile,%
%  srcline,%
%  startatroot,%
%  uri,%
%  view,%
%}
%    \end{macrocode}
%    \begin{macro}{\bookmarksetup}
%    \begin{macrocode}
\newcommand*{\bookmarksetup}{\SetKeys[BKM]}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@setup}
%    \begin{macrocode}
\def\BKM@setup#1{%
  \bookmarksetup{#1}%
  \ifx\BKM@HookNext\@empty
  \else
    \expandafter\bookmarksetup\expandafter{\BKM@HookNext}%
    \BKM@HookNextClear
  \fi
  \BKM@hook
  \ifBKM@keeplevel
  \else
    \xdef\BKM@currentlevel{\BKM@level}%
  \fi
}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\bookmarksetupnext}
%    \begin{macrocode}
\newcommand*{\bookmarksetupnext}[1]{%
  \BKM@GlobalAppendToMacro\BKM@HookNext{,#1}%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@HookNextClear}
%    \begin{macrocode}
\def\BKM@HookNextClear{%
  \global\let\BKM@HookNext\@empty
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@HookNext}
%    \begin{macrocode}
\BKM@HookNextClear
%    \end{macrocode}
%    \end{macro}
%
% \begin{keydecl}{draft,final}
%    \begin{macrocode}
\DeclareKeys[BKM]
 {
   ,draft.legacy_if_set:n         = BKM@draft
   ,final.legacy_if_set_inverse:n = BKM@draft
   ,draft.usage:n = load
   ,final.usage:n = load 
 }
%    \end{macrocode}
% \end{keydecl}
% 
% \begin{keydecl}{open}
%    \begin{macrocode}
\DeclareKeys[BKM]
 {
   ,open.legacy_if_set:n = BKM@open
   ,open.initial:e = \ifHy@bookmarksopen true\else false\fi
 }
%    \end{macrocode}
% \end{keydecl}
%    \begin{macro}[module=BKM]{\bookmark@open}
%    \begin{macrocode}
\def\bookmark@open{%
  \ifBKM@open\@ne\else\z@\fi
}
%    \end{macrocode}
%    \end{macro}
% \begin{keydecl}{openlevel}   
%    \begin{macrocode}
\DeclareKeys[BKM]
 {
   ,openlevel.tl_set:N  = \BKM@openlevel
   ,openlevel.initial:e = \number\@bookmarksopenlevel
 }
%    \end{macrocode}
% \end{keydecl}
% 

% \begin{macro}[module=BKM]{\BKM@depth}
%    \begin{macrocode}
\@ifundefined{Hy@bookmarksdepth}{%
  \def\BKM@depth{\c@tocdepth}%
}{%
  \let\BKM@depth\Hy@bookmarksdepth
}
%    \end{macrocode}
% \end{macro}
% 
% \begin{keydecl}{depth}
%    \begin{macrocode}
\DeclareKeys[BKM]
 {
   ,depth.code:n = 
    {%
     \edef\BKM@param{#1}%
     \ifx\BKM@param\@empty
       \def\BKM@depth{\c@tocdepth}%
     \else
       \@ifundefined{toclevel@\BKM@param}{%
         \@onelevel@sanitize\BKM@param
         \edef\BKM@temp{\expandafter\@car\BKM@param\@nil}%
         \ifcase 0\expandafter\ifx\BKM@temp-1\fi
                 \expandafter\ifnum\expandafter`\BKM@temp>47 %
                   \expandafter\ifnum\expandafter`\BKM@temp<58 %
                     1%
                   \fi
                 \fi
                 \relax
           \PackageWarning{bookmark}{%
             Unknown document division name (\BKM@param)\MessageBreak
             for option `depth'%
           }%
         \else
           \BKM@SetDepthOrLevel\BKM@depth\BKM@param
         \fi
       }{%
         \BKM@SetDepthOrLevel\BKM@depth{%
           \csname toclevel@\BKM@param\endcsname
         }%
       }%
     \fi
   }
 }
%    \end{macrocode}
% \end{keydecl}
%    \begin{macro}[module=BKM]{\bookmark@depth}
%    \begin{macrocode}
\def\bookmark@depth{\BKM@depth}
%    \end{macrocode}
%    \end{macro}
%    
%    \begin{macro}[module=BKM]{\BKM@SetDepthOrLevel}
%    \begin{macrocode}
\def\BKM@SetDepthOrLevel#1#2{%
  \begingroup
    \setbox\z@=\hbox{%
      \count@=#2\relax
      \expandafter
    }%
  \expandafter\endgroup
  \expandafter\def\expandafter#1\expandafter{\the\count@}%
}
%    \end{macrocode}
%    \end{macro}
%    
% \begin{macro}[module=BKM]{\BKM@set@level}
%    \begin{macrocode}
\newcommand\BKM@set@level[1]{%
  \edef\BKM@param{#1}%
  \ifx\BKM@param\BKM@MacroCurrentLevel
    \let\BKM@level\BKM@param
  \else
    \@ifundefined{toclevel@\BKM@param}{%
      \@onelevel@sanitize\BKM@param
      \edef\BKM@temp{\expandafter\@car\BKM@param\@nil}%
      \ifcase 0\expandafter\ifx\BKM@temp-1\fi
              \expandafter\ifnum\expandafter`\BKM@temp>47 %
                \expandafter\ifnum\expandafter`\BKM@temp<58 %
                  1%
                \fi
              \fi
              \relax
        \PackageWarning{bookmark}{%
          Unknown document division name (\BKM@param)\MessageBreak
          for option `level'%
        }%
      \else
        \BKM@SetDepthOrLevel\BKM@level\BKM@param
      \fi
    }{%
      \BKM@SetDepthOrLevel\BKM@level{%
        \csname toclevel@\BKM@param\endcsname
      }%
    }%
  \fi
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[module=BKM]{\BKM@level}
%    \begin{macrocode}
\def\BKM@level{\BKM@currentlevel}
%    \end{macrocode}
% \end{macro}
% \begin{keydecl}{level}
%    \begin{macrocode}
\DeclareKeys[BKM]
 {
   ,level.code:n    = \BKM@set@level{#1}
   ,level.default:n = \BKM@currentlevel
 }
%    \end{macrocode}
% \end{keydecl}
%    \begin{macro}[module=BKM]{\BKM@MacroCurrentLevel}
%    \begin{macrocode}
\def\BKM@MacroCurrentLevel{\BKM@currentlevel}
%    \end{macrocode}
%    \end{macro}
% \begin{keydecl}{keeplevel,startatroot}    
%    \begin{macrocode}
\DeclareKeys[BKM]
 {
   ,keeplevel.legacy_if_set:n    = BKM@keeplevel
   ,startatroot.legacy_if_set:n = BKM@startatroot
 }
%    \end{macrocode}
% \end{keydecl}
%    \begin{macro}[module=BKM]{\BKM@startatrootfalse}
%    \begin{macrocode}
\def\BKM@startatrootfalse{%
  \global\let\ifBKM@startatroot\iffalse
}
%    \end{macrocode}
%    \end{macro}
%    
%    \begin{macro}[module=BKM]{\BKM@startatroottrue}
%    \begin{macrocode}
\def\BKM@startatroottrue{%
  \global\let\ifBKM@startatroot\iftrue
}
%    \end{macrocode}
%    \end{macro}
% \begin{keydecl}{rellevel}    
%    \begin{macrocode}
\DeclareKeys[BKM]
 {
   ,rellevel.code:n = {\BKM@CalcExpr\BKM@level{#1}+\BKM@currentlevel}
 }
%    \end{macrocode}
% \end{keydecl}
%    \begin{macro}[module=BKM]{\bookmark@level}
%    \begin{macrocode}
\def\bookmark@level{\BKM@level}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@currentlevel}
%    \begin{macrocode}
\def\BKM@currentlevel{0}
%    \end{macrocode}
%    \end{macro}
% \begin{keydecl}{numbered}    
%    Make \xpackage{bookmark}'s option \xoption{numbered} an alias
%    for \xpackage{hyperref}'s \xoption{bookmarksnumbered}.
%    \begin{macrocode}
\DeclareKeys[BKM]
 {
   ,numbered.legacy_if_set:n = BKM@numbered
   ,numbered.initial:e = \ifHy@bookmarksnumbered true\else false\fi
 }
\g@addto@macro\BKM@numberedtrue{%
  \let\ifHy@bookmarksnumbered\iftrue
}
\g@addto@macro\BKM@numberedfalse{%
  \let\ifHy@bookmarksnumbered\iffalse
}
\g@addto@macro\Hy@bookmarksnumberedtrue{%
  \let\ifBKM@numbered\iftrue
}
\g@addto@macro\Hy@bookmarksnumberedfalse{%
  \let\ifBKM@numbered\iffalse
}
%    \end{macrocode}
% \end{keydecl}
%
%    \begin{macro}[module=BKM]{\bookmark@numbered}
%    \begin{macrocode}
\def\bookmark@numbered{%
  \ifBKM@numbered\@ne\else\z@\fi
}
%    \end{macrocode}
%    \end{macro}
%
% \paragraph{Redefinitions \xpackage{hyperref}'s options}
%
%    \begin{macro}[module=BKM]{\BKM@PatchHyperrefOption}
%    \begin{macrocode}
\def\BKM@PatchHyperrefOption#1{%
  \expandafter\BKM@@PatchHyperrefOption\csname KV@Hyp@#1\endcsname%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@@PatchHyperrefOption}
%    \begin{macrocode}
\def\BKM@@PatchHyperrefOption#1{%
  \expandafter\BKM@@@PatchHyperrefOption#1{##1}\BKM@nil#1%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@@@PatchHyperrefOption}
%    \begin{macrocode}
\def\BKM@@@PatchHyperrefOption#1\BKM@nil#2#3{%
  \def#2##1{%
    #1%
    \bookmarksetup{#3={##1}}%
  }%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
\BKM@PatchHyperrefOption{bookmarksopen}{open}
\BKM@PatchHyperrefOption{bookmarksopenlevel}{openlevel}
\BKM@PatchHyperrefOption{bookmarksdepth}{depth}
%    \end{macrocode}
%
% \paragraph{Font style options.}
%
%    Caution: Package \xpackage{bitset} is zero-based, the
%    PDF specifications starts with one.
% \begin{keydecl}{italic,bold}    
%    \begin{macrocode}
\bitsetReset{BKM@FontStyle}%
\DeclareKeys[BKM]
 {
   ,italic.code:n = 
     {
       \expandafter\ifx\csname if#1\endcsname\iftrue
         \bitsetSet{BKM@FontStyle}{0}%
       \else
         \bitsetClear{BKM@FontStyle}{0}%
       \fi
     }
   ,italic.default:n = true  
   ,bold.code:n = 
    {
      \expandafter\ifx\csname if#1\endcsname\iftrue
        \bitsetSet{BKM@FontStyle}{1}%
      \else
        \bitsetClear{BKM@FontStyle}{1}%
      \fi
    }
   ,bold.default:n = true  
 }
%    \end{macrocode}
% \end{keydecl}
%    \begin{macro}[module=BKM]{\bookmark@italic}
%    \begin{macrocode}
\def\bookmark@italic{%
  \ifnum\bitsetGet{BKM@FontStyle}{0}=1 \@ne\else\z@\fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\bookmark@bold}
%    \begin{macrocode}
\def\bookmark@bold{%
  \ifnum\bitsetGet{BKM@FontStyle}{1}=1 \@ne\else\z@\fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@PrintStyle}
%    \begin{macrocode}
\def\BKM@PrintStyle{%
  \bitsetGetDec{BKM@FontStyle}%
}%
%    \end{macrocode}
%    \end{macro}
%
% \paragraph{Options for color.}
%
% If the PDF management is loaded we make use of l3color commands for color expressions,
% without it they only work if \xpackage{xcolor} has been loaded.
% 
%  \begin{macro}[module=BKM]{\__BKM_color_set:nn,\__BKM_color_set_aux:nwn}
%   Color keys need to parse color expressions. Two input types are supported:
%  |color=[rgb]{1,0,.5}| and |color=red!50!blue|.
%    \begin{macrocode}
\ExplSyntaxOn
\cs_new_protected:Npn \__BKM_color_set:nn #1 #2
 {
   \tl_if_head_eq_charcode:nNTF {#2}[ %]
    {
      \__BKM_color_set_aux:nwn  { #1 } #2
    }
    {
      \color_set:nn {#1} {#2}
    }
 }

\cs_new_protected:Npn \__BKM_color_set_aux:nwn #1 [#2] #3
  {
     \color_set:nnn {#1}{#2}{#3}
  }

\cs_generate_variant:Nn \__BKM_color_set:nn {ne}
\str_new:N\g__BKM_colormodel_str
%    \end{macrocode}
% \end{macro}
%\begin{keydecl}{colormodel}
%    \begin{macrocode}
\keys_define:nn { BKM }
  {
    ,colormodel .choices:nn =
      {rgb,cmyk}
     { \str_gset:Nn \g__BKM_colormodel_str {space-sep-#1}}
    ,colormodel .initial:n ={rgb}
  }
%    \end{macrocode}
% \end{keydecl}
% If the PDF management is active, we use the l3color export function.
% \begin{keydecl}{color}
%    \begin{macrocode}
\IfPDFManagementActiveTF
 {
  \DeclareKeys[BKM]
    {
      ,color.code:n =
       {
        \tl_if_blank:nTF {#1}
          { \cs_set_eq:NN\BKM@color\@empty }
          {
            \__BKM_color_set:ne {__BKM/tmpa}{#1}
            \color_export:nVN
              {__BKM/tmpa}
              \g__BKM_colormodel_str
              \BKM@color
          }
       } 
    }
 }
 {
   \DeclareKeys[BKM]
    {
      ,color.code:n = 
        {\HyColor@BookmarkColor{#1}\BKM@color{bookmark}{color}}   
    }
 }
\ExplSyntaxOff       
%    \end{macrocode}
% \end{keydecl}
% 
%    \begin{macro}[module=BKM]{\BKM@color}
%    \begin{macrocode}
\let\BKM@color\@empty
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\bookmark@color}
%    \begin{macrocode}
\def\bookmark@color{\BKM@color}
%    \end{macrocode}
%    \end{macro}
%
% \subsubsection{Action options}
%
% \begin{keydecl}{dest,named,uri,gotor,rawaction}
%    \begin{macrocode}
\ExplSyntaxOn
\def\BKM@temp#1{%
  \DeclareKeys[BKM]{#1.tl_set:c = BKM@#1}%
  \expandafter\edef\csname bookmark@#1\endcsname{%
    \expandafter\noexpand\csname BKM@#1\endcsname
  }%
}
\ExplSyntaxOff
%    \end{macrocode}
%    \begin{macro}[module=BKM]{\bookmark@dest}
%    \begin{macrocode}
\BKM@temp{dest}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\bookmark@named}
%    \begin{macrocode}
\BKM@temp{named}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\bookmark@uri}
%    \begin{macrocode}
\BKM@temp{uri}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\bookmark@gotor}
%    \begin{macrocode}
\BKM@temp{gotor}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\bookmark@rawaction}
%    \begin{macrocode}
\BKM@temp{rawaction}
%    \end{macrocode}
%    \end{macro}
% \end{keydecl}
% \begin{keydecl}{page}
%    \begin{macrocode}
\DeclareKeys[BKM]
 {
   ,page.code:n = 
     {%
      \def\BKM@page{#1}%
      \ifx\BKM@page\@empty
      \else
       \edef\BKM@page{\number\BKM@page}%
       \ifnum\BKM@page>\z@
       \else
        \PackageError{bookmark}{Page must be positive}\@ehc
        \def\BKM@page{1}%
       \fi
      \fi 
     }
 }
%    \end{macrocode}
% \end{keydecl}
%    \begin{macro}[module=BKM]{\BKM@page}
%    \begin{macrocode}
\let\BKM@page\@empty
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\bookmark@page}
%    \begin{macrocode}
\def\bookmark@page{\BKM@@page}
%    \end{macrocode}
%    \end{macro}
% \begin{keydecl}{view}
%    \begin{macrocode}
\DeclareKeys[BKM]
 {
   ,view.code:n = {\BKM@CheckView{#1}}
 }
%    \end{macrocode}
% \end{keydecl}
%    \begin{macro}[module=BKM]{\BKM@view}
%    \begin{macrocode}
\let\BKM@view\@empty
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\bookmark@view}
%    \begin{macrocode}
\def\bookmark@view{\BKM@view}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@CheckView}
%    \begin{macrocode}
\def\BKM@CheckView#1{%
  \BKM@CheckViewType#1 \@nil
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@CheckViewType}
%    \begin{macrocode}
\def\BKM@CheckViewType#1 #2\@nil{%
  \def\BKM@type{#1}%
  \@onelevel@sanitize\BKM@type
  \BKM@TestViewType{Fit}{}%
  \BKM@TestViewType{FitB}{}%
  \BKM@TestViewType{FitH}{%
    \BKM@CheckParam#2 \@nil{top}%
  }%
  \BKM@TestViewType{FitBH}{%
    \BKM@CheckParam#2 \@nil{top}%
  }%
  \BKM@TestViewType{FitV}{%
    \BKM@CheckParam#2 \@nil{bottom}%
  }%
  \BKM@TestViewType{FitBV}{%
    \BKM@CheckParam#2 \@nil{bottom}%
  }%
  \BKM@TestViewType{FitR}{%
    \BKM@CheckRect{#2}{ }%
  }%
  \BKM@TestViewType{XYZ}{%
    \BKM@CheckXYZ{#2}{ }%
  }%
  \@car{%
    \PackageError{bookmark}{%
      Unknown view type `\BKM@type',\MessageBreak
      using `FitH' instead%
    }\@ehc
    \def\BKM@view{FitH}%
  }%
  \@nil
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@TestViewType}
%    \begin{macrocode}
\def\BKM@TestViewType#1{%
  \def\BKM@temp{#1}%
  \@onelevel@sanitize\BKM@temp
  \ifx\BKM@type\BKM@temp
    \let\BKM@view\BKM@temp
    \expandafter\@car
  \else
    \expandafter\@gobble
  \fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@CheckParam}
%    \begin{macrocode}
\def\BKM@CheckParam#1 #2\@nil#3{%
  \def\BKM@param{#1}%
  \ifx\BKM@param\@empty
    \PackageWarning{bookmark}{%
      Missing parameter (#3) for `\BKM@type',\MessageBreak
      using 0%
    }%
    \def\BKM@param{0}%
  \else
    \BKM@CalcParam
  \fi
  \edef\BKM@view{\BKM@view\space\BKM@param}%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@CheckRect}
%    \begin{macrocode}
\def\BKM@CheckRect#1#2{%
  \BKM@@CheckRect#1#2#2#2#2\@nil
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@@CheckRect}
%    \begin{macrocode}
\def\BKM@@CheckRect#1 #2 #3 #4 #5\@nil{%
  \def\BKM@temp{0}%
  \def\BKM@param{#1}%
  \ifx\BKM@param\@empty
    \def\BKM@param{0}%
    \def\BKM@temp{1}%
  \else
    \BKM@CalcParam
  \fi
  \edef\BKM@view{\BKM@view\space\BKM@param}%
  \def\BKM@param{#2}%
  \ifx\BKM@param\@empty
    \def\BKM@param{0}%
    \def\BKM@temp{1}%
  \else
    \BKM@CalcParam
  \fi
  \edef\BKM@view{\BKM@view\space\BKM@param}%
  \def\BKM@param{#3}%
  \ifx\BKM@param\@empty
    \def\BKM@param{0}%
    \def\BKM@temp{1}%
  \else
    \BKM@CalcParam
  \fi
  \edef\BKM@view{\BKM@view\space\BKM@param}%
  \def\BKM@param{#4}%
  \ifx\BKM@param\@empty
    \def\BKM@param{0}%
    \def\BKM@temp{1}%
  \else
    \BKM@CalcParam
  \fi
  \edef\BKM@view{\BKM@view\space\BKM@param}%
  \ifnum\BKM@temp>\z@
    \PackageWarning{bookmark}{Missing parameters for `\BKM@type'}%
  \fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@CheckXYZ}
%    \begin{macrocode}
\def\BKM@CheckXYZ#1#2{%
  \BKM@@CheckXYZ#1#2#2#2\@nil
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@@CheckXYZ}
%    \begin{macrocode}
\def\BKM@@CheckXYZ#1 #2 #3 #4\@nil{%
  \def\BKM@param{#1}%
  \let\BKM@temp\BKM@param
  \@onelevel@sanitize\BKM@temp
  \ifx\BKM@param\@empty
    \let\BKM@param\BKM@null
  \else
    \ifx\BKM@temp\BKM@null
    \else
      \BKM@CalcParam
    \fi
  \fi
  \edef\BKM@view{\BKM@view\space\BKM@param}%
  \def\BKM@param{#2}%
  \let\BKM@temp\BKM@param
  \@onelevel@sanitize\BKM@temp
  \ifx\BKM@param\@empty
    \let\BKM@param\BKM@null
  \else
    \ifx\BKM@temp\BKM@null
    \else
      \BKM@CalcParam
    \fi
  \fi
  \edef\BKM@view{\BKM@view\space\BKM@param}%
  \def\BKM@param{#3}%
  \ifx\BKM@param\@empty
    \let\BKM@param\BKM@null
  \fi
  \edef\BKM@view{\BKM@view\space\BKM@param}%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@null}
%    \begin{macrocode}
\def\BKM@null{null}
\@onelevel@sanitize\BKM@null
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}[module=BKM]{\BKM@CalcParam}
%    \begin{macrocode}
\def\BKM@CalcParam{%
  \begingroup
  \let\calc\@firstofone
  \expandafter\BKM@@CalcParam\BKM@param\@empty\@empty\@nil
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@@CalcParam}
%    \begin{macrocode}
\def\BKM@@CalcParam#1#2#3\@nil{%
  \ifx\calc#1%
    \@ifundefined{calc@assign@dimen}{%
      \@ifundefined{dimexpr}{%
        \setlength{\dimen@}{#2}%
      }{%
        \setlength{\dimen@}{\dimexpr#2\relax}%
      }%
    }{%
      \setlength{\dimen@}{#2}%
    }%
    \dimen@.99626\dimen@
    \edef\BKM@param{\strip@pt\dimen@}%
    \expandafter\endgroup
    \expandafter\def\expandafter\BKM@param\expandafter{\BKM@param}%
  \else
    \endgroup
  \fi
}
%    \end{macrocode}
%    \end{macro}
%
% \subsubsection{Option \xoption{atend}}
%
% \begin{keydecl}{atend}
%    \begin{macrocode}
\DeclareKeys[BKM]
 {
   ,atend.legacy_if_set:n = BKM@atend
   ,atend.usage:n = load
 }
%    \end{macrocode}
% \end{keydecl}
% \subsubsection{Option \xoption{style}}
%
%    \begin{macro}{\bookmarkdefinestyle}
%    \begin{macrocode}
\newcommand*{\bookmarkdefinestyle}[2]{%
  \@ifundefined{BKM@style@#1}{%
  }{%
    \PackageInfo{bookmark}{Redefining style `#1'}%
  }%
  \@namedef{BKM@style@#1}{#2}%
}
%    \end{macrocode}
%    \end{macro}
% \begin{keydecl}{style}   
%    \begin{macrocode}
\DeclareKeys[BKM]
 {
   ,style.code:n = {\BKM@StyleCall{#1}}
 }
\newif\ifBKM@ok
%    \end{macrocode}
% \end{keydecl}
%    \begin{macro}[module=BKM]{\BKM@StyleCall}
%    \begin{macrocode}
\def\BKM@StyleCall#1{%
  \@ifundefined{BKM@style@#1}{%
    \PackageWarning{bookmark}{%
      Ignoring unknown style `#1'%
    }%
  }{%
%    \end{macrocode}
%    Check style stack.
%    \begin{macrocode}
    \BKM@oktrue
    \edef\BKM@StyleCurrent{#1}%
    \@onelevel@sanitize\BKM@StyleCurrent
    \let\BKM@StyleEntry\BKM@StyleEntryCheck
    \BKM@StyleStack
    \ifBKM@ok
      \expandafter\@firstofone
    \else
      \PackageError{bookmark}{%
        Ignoring recursive call of style `\BKM@StyleCurrent'%
      }\@ehc
      \expandafter\@gobble
    \fi
    {%
%    \end{macrocode}
%    Push current style on stack.
%    \begin{macrocode}
      \let\BKM@StyleEntry\relax
      \edef\BKM@StyleStack{%
        \BKM@StyleEntry{\BKM@StyleCurrent}%
        \BKM@StyleStack
      }%
%    \end{macrocode}
%   Call style.
%    \begin{macrocode}
      \expandafter\expandafter\expandafter\bookmarksetup
      \expandafter\expandafter\expandafter{%
        \csname BKM@style@\BKM@StyleCurrent\endcsname
      }%
%    \end{macrocode}
%    Pop current style from stack.
%    \begin{macrocode}
      \BKM@StyleStackPop
    }%
  }%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@StyleStackPop}
%    \begin{macrocode}
\def\BKM@StyleStackPop{%
  \let\BKM@StyleEntry\relax
  \edef\BKM@StyleStack{%
    \expandafter\@gobbletwo\BKM@StyleStack
  }%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@StyleEntryCheck}
%    \begin{macrocode}
\def\BKM@StyleEntryCheck#1{%
  \def\BKM@temp{#1}%
  \ifx\BKM@temp\BKM@StyleCurrent
    \BKM@okfalse
  \fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[module=BKM]{\BKM@StyleStack}
%    \begin{macrocode}
\def\BKM@StyleStack{}
%    \end{macrocode}
%    \end{macro}
%
% \subsubsection{Options for source file location}
%
% \begin{keydecl}{srcline,srcfile}
%    \begin{macrocode}
\DeclareKeys[BKM]
 {
   ,srcline.tl_set:N = \BKM@srcline
   ,srcfile.tl_set:N = \BKM@srcfile
 }
%    \end{macrocode}
% \end{keydecl}
% \subsubsection{Hook support}
%
%    \begin{macro}[module=BKM]{\BKM@hook}
%    \begin{macrocode}
\def\BKM@hook{}
%    \end{macrocode}
%    \end{macro}
% \begin{keydecl}{addtohook}    
%    \begin{macrocode}
\DeclareKeys[BKM]
 {
   ,addtohook.code:n = {\BKM@LocalAppendToMacro\BKM@hook{#1}}
 }
%    \end{macrocode}
% \end{keydecl}
%    \begin{macro}{\bookmarkget}
%    \begin{macrocode}
\newcommand*{\bookmarkget}[1]{%
  \romannumeral0%
  \@ifundefined{bookmark@#1}{%
    \BKM@space
  }{%
    \expandafter\expandafter\expandafter\BKM@space
    \csname bookmark@#1\endcsname
  }%
}
%    \end{macrocode}
%    \end{macro}
%
% \subsubsection{Driver setup and loading}
%
% \paragraph{Driver detection.}
%
%    \begin{macro}[module=BKM]{\BKM@DefineDriverKey}
%    \begin{macrocode}
\def\BKM@DefineDriverKey#1{%
  \DeclareKeys[BKM]
   {
    ,#1.code:n   = 
      {\def\BKM@driver{#1}%
      \PackageWarning{bookmark}{Option '#1' is obsolete
        and ignored}{}}
   }
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
\BKM@DefineDriverKey{pdftex}
\BKM@DefineDriverKey{dvips}
\BKM@DefineDriverKey{dvipdfm}
\BKM@DefineDriverKey{dvipdfmx}
\BKM@DefineDriverKey{xetex}
\BKM@DefineDriverKey{vtex}
\DeclareKeys[BKM]
 {
   ,dvipdfmx-outline-open.code:n = 
     {%
       \PackageWarning{bookmark}{Option 'dvipdfmx-outline-open' is obsolete
        and ignored}{}
     }   
   ,dvipdfmx-outline-open.default:n=true 
 }   
%    \end{macrocode}
%    \begin{macrocode}
\InputIfFileExists{bookmark.cfg}{}{}
%    \end{macrocode}
%
% \paragraph{Process options.}
%
%    \begin{macrocode}
\let\BKM@raw@classoptionlist\@raw@classoptionslist
\let\@raw@classoptionslist\relax
\ProcessKeyOptions[BKM]
\let\@raw@classoptionslist\BKM@raw@classoptionlist
%    \end{macrocode}
%
% \paragraph{Option \xoption{draft}}
%
%    \begin{macrocode}
\ifBKM@draft
  \PackageWarningNoLine{bookmark}{Draft mode on}%
  \let\bookmarksetup\@gobble
  \let\BookmarkAtEnd\@gobble
  \let\bookmarkdefinestyle\@gobbletwo
  \let\bookmarkget\@gobble
  \let\pdfbookmark\@undefined
  \newcommand*{\pdfbookmark}[3][]{}%
  \let\currentpdfbookmark\@gobbletwo
  \let\subpdfbookmark\@gobbletwo
  \let\belowpdfbookmark\@gobbletwo
  \newcommand*{\bookmark}[2][]{}%
  \renewcommand*{\Hy@writebookmark}[5]{}%
  \let\ReadBookmarks\relax
  \let\BKM@DefGotoNameAction\@gobbletwo % package `hypdestopt'
  \expandafter\endinput
\fi
%    \end{macrocode}
%
% \paragraph{Driver loading.}
%
%    \begin{macrocode}
\ExplSyntaxOn
\ifvtex
 \def\BKM@driver{vtex}
\else
 \sys_ensure_backend:
 \str_case:Nn \c_sys_backend_str
  {
    {pdftex}  {\def\BKM@driver{pdftex}}
    {luatex}  {\def\BKM@driver{luatex}}
    {xetex}   {\def\BKM@driver{xetex}}
    {dvipdfmx}{\def\BKM@driver{dvipdfmx}}
    {dvips}   {\def\BKM@driver{dvips}}
  } 
\fi 
\ExplSyntaxOff 
\InputIfFileExists{bkm-\BKM@driver.def}{}{}
%    \end{macrocode}
%
% \subsubsection{Compatibility for \xpackage{hyperref}}
%
%    \begin{macro}{\pdfbookmark}
%    \begin{macrocode}
\let\pdfbookmark\@undefined
\newcommand*{\pdfbookmark}[3][0]{%
  \bookmark[level=#1,dest={#3.#1}]{#2}%
  \hyper@anchorstart{#3.#1}\hyper@anchorend
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\currentpdfbookmark}
%    \begin{macrocode}
\def\currentpdfbookmark{%
  \pdfbookmark[\BKM@currentlevel]%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\subpdfbookmark}
%    \begin{macrocode}
\def\subpdfbookmark{%
  \BKM@CalcExpr\BKM@CalcResult\BKM@currentlevel+1%
  \expandafter\pdfbookmark\expandafter[\BKM@CalcResult]%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\belowpdfbookmark}
%    \begin{macrocode}
\def\belowpdfbookmark#1#2{%
  \xdef\BKM@gtemp{\number\BKM@currentlevel}%
  \subpdfbookmark{#1}{#2}%
  \global\let\BKM@currentlevel\BKM@gtemp
}
%    \end{macrocode}
%    \end{macro}
%
%    Section number, text, label, level, file
%    \begin{macro}[module=]{\Hy@writebookmark}
%    \begin{macrocode}
\def\Hy@writebookmark#1#2#3#4#5{%
  \ifnum#4>\BKM@depth\relax
  \else
    \edef\BKM@type{#5}%
    \ifx\BKM@type\Hy@bookmarkstype
      \begingroup
        \ifBKM@numbered
          \let\numberline\Hy@numberline
          \let\booknumberline\Hy@numberline
          \let\partnumberline\Hy@numberline
          \let\chapternumberline\Hy@numberline
        \else
          \let\numberline\@gobble
          \let\booknumberline\@gobble
          \let\partnumberline\@gobble
          \let\chapternumberline\@gobble
        \fi
        \bookmark[level=#4,dest={\HyperDestNameFilter{#3}}]{#2}%
      \endgroup
    \fi
  \fi
}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}[int,module=]{\ReadBookmarks}
%    \begin{macrocode}
\let\ReadBookmarks\relax
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \subsection{Driver for dvipdfm}
%
%    \begin{macrocode}
%<*dvipdfmx>
\NeedsTeXFormat{LaTeX2e}
\ProvidesFile{bkm-dvipdfmx.def}%
  [2026-05-21 v1.32 bookmark driver for dvipdfm (HO)]%
%</dvipdfmx>  
%    \end{macrocode}
%    \begin{macrocode}
%<*xetex>
\NeedsTeXFormat{LaTeX2e}
\ProvidesFile{bkm-xetex.def}%
  [2026-05-21 v1.32 bookmark driver for xetex (HO)]%
%</xetex>  
%    \end{macrocode}
%    \begin{macrocode}
%<*dvipdfmx|xetex>
%    \end{macrocode}
%    \begin{macro}[int]{\BKM@id}
%    \begin{macrocode}
\newcount\BKM@id
\BKM@id=\z@
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}[int]{\BKM@0}
%    \begin{macrocode}
\@namedef{BKM@0}{000}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\ifBKM@sw}
%    \begin{macrocode}
\newif\ifBKM@sw
%    \end{macrocode}
%    \end{macro}
%    
% \begin{macro}[int]{\BKM@struct@dest}
% Support for structure destinations in the outline.
%    \begin{macrocode}
\newcommand\BKM@struct@dest{}
\ExplSyntaxOn
\IfDocumentMetadataTF
  {
    \tag_if_active:T
     {
       \def\BKM@struct@dest{/SD~@pdf.SDest.\BKM@dest} 
     }
     
  }{}
\ExplSyntaxOff
%    \end{macrocode}
% \end{macro}
%
%    \begin{macro}{\bookmark}
%    \begin{macrocode}
\newcommand*{\bookmark}[2][]{%
  \if@filesw
    \begingroup
      \def\bookmark@text{#2}%
      \BKM@setup{#1}%
      \edef\BKM@prev{\the\BKM@id}%
      \global\advance\BKM@id\@ne
      \BKM@swtrue
      \@whilesw\ifBKM@sw\fi{%
        \def\BKM@abslevel{1}%
        \ifnum\ifBKM@startatroot\z@\else\BKM@prev\fi=\z@
          \BKM@startatrootfalse
          \expandafter\xdef\csname BKM@\the\BKM@id\endcsname{%
            0{\BKM@level}\BKM@abslevel
          }%
          \BKM@swfalse
        \else
          \expandafter\expandafter\expandafter\BKM@getx
              \csname BKM@\BKM@prev\endcsname
          \ifnum\BKM@level>\BKM@x@level\relax
            \BKM@CalcExpr\BKM@abslevel\BKM@x@abslevel+1%
            \expandafter\xdef\csname BKM@\the\BKM@id\endcsname{%
              {\BKM@prev}{\BKM@level}\BKM@abslevel
            }%
            \BKM@swfalse
          \else
            \let\BKM@prev\BKM@x@parent
          \fi
        \fi
      }%
      \csname HyPsd@XeTeXBigCharstrue\endcsname
      \pdfstringdef\BKM@title{\bookmark@text}%
      \edef\BKM@FLAGS{\BKM@PrintStyle}%
      \let\BKM@action\@empty
      \ifx\BKM@gotor\@empty
        \ifx\BKM@dest\@empty
          \ifx\BKM@named\@empty
            \ifx\BKM@rawaction\@empty
              \ifx\BKM@uri\@empty
                \ifx\BKM@page\@empty
                  \PackageError{bookmark}{Missing action}\@ehc
                  \edef\BKM@action{/Dest[@page1/Fit]}%
                \else
                  \ifx\BKM@view\@empty
                    \def\BKM@view{Fit}%
                  \fi
                  \edef\BKM@action{/Dest[@page\BKM@page/\BKM@view]}%
                \fi
              \else
                \BKM@EscapeString\BKM@uri
                \edef\BKM@action{%
                  /A<<%
                    /S/URI%
                    /URI(\BKM@uri)%
                  >>%
                }%
              \fi
            \else
              \edef\BKM@action{/A<<\BKM@rawaction>>}%
            \fi
          \else
            \BKM@EscapeName\BKM@named
            \edef\BKM@action{%
              /A<</S/Named/N/\BKM@named>>%
            }%
          \fi
        \else
          \BKM@EscapeString\BKM@dest
          \edef\BKM@action{%
            /A<<%
              /S/GoTo%
              /D(\BKM@dest)%
              \BKM@struct@dest
            >>%
          }%
        \fi
      \else
        \ifx\BKM@dest\@empty
          \ifx\BKM@page\@empty
            \def\BKM@page{0}%
          \else
            \BKM@CalcExpr\BKM@page\BKM@page-1%
          \fi
          \ifx\BKM@view\@empty
            \def\BKM@view{Fit}%
          \fi
          \edef\BKM@action{/D[\BKM@page/\BKM@view]}%
        \else
          \BKM@EscapeString\BKM@dest
          \edef\BKM@action{/D(\BKM@dest)}%
        \fi
        \BKM@EscapeString\BKM@gotor
        \edef\BKM@action{%
          /A<<%
            /S/GoToR%
            /F(\BKM@gotor)%
            \BKM@action
          >>%
        }%
      \fi
      \special{pdf:%
        out
              [%
              \ifBKM@open
                \ifnum\BKM@level<%
                    \expandafter\@firstofone\expandafter
                    {\number\BKM@openlevel} %
                \else
                  -%
                \fi
              \else
                -%
              \fi
              ] %
            \BKM@abslevel
        <<%
          /Title(\BKM@title)%
          \ifx\BKM@color\@empty
          \else
            /C[\BKM@color]%
          \fi
          \ifnum\BKM@FLAGS>\z@
            /F \BKM@FLAGS
          \fi
          \BKM@action
        >>%
      }%
    \endgroup
  \fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\BKM@getx}
%    \begin{macrocode}
\def\BKM@getx#1#2#3{%
  \def\BKM@x@parent{#1}%
  \def\BKM@x@level{#2}%
  \def\BKM@x@abslevel{#3}%
}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macrocode}
%</dvipdfmx|xetex>
%    \end{macrocode}
%
% \subsection{Driver for \hologo{VTeX}}
%
%    \begin{macrocode}
%<*vtex>
\NeedsTeXFormat{LaTeX2e}
\ProvidesFile{bkm-vtex.def}%
  [2026-05-21 v1.32 bookmark driver for VTeX (HO)]%
%    \end{macrocode}
%
%    \begin{macrocode}
\ifvtexpdf
\else
  \PackageWarningNoLine{bookmark}{%
    The VTeX driver only supports PDF mode%
  }%
\fi
%    \end{macrocode}
%
%    \begin{macro}[int]{\BKM@id}
%    \begin{macrocode}
\newcount\BKM@id
\BKM@id=\z@
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}[int]{\BKM@0}
%    \begin{macrocode}
\@namedef{BKM@0}{00}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\ifBKM@sw}
%    \begin{macrocode}
\newif\ifBKM@sw
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\bookmark}
%    \begin{macrocode}
\newcommand*{\bookmark}[2][]{%
  \if@filesw
    \begingroup
      \def\bookmark@text{#2}%
      \BKM@setup{#1}%
      \edef\BKM@prev{\the\BKM@id}%
      \global\advance\BKM@id\@ne
      \BKM@swtrue
      \@whilesw\ifBKM@sw\fi{%
        \ifnum\ifBKM@startatroot\z@\else\BKM@prev\fi=\z@
          \BKM@startatrootfalse
          \def\BKM@parent{0}%
          \expandafter\xdef\csname BKM@\the\BKM@id\endcsname{%
            0{\BKM@level}%
          }%
          \BKM@swfalse
        \else
          \expandafter\expandafter\expandafter\BKM@getx
              \csname BKM@\BKM@prev\endcsname
          \ifnum\BKM@level>\BKM@x@level\relax
            \let\BKM@parent\BKM@prev
            \expandafter\xdef\csname BKM@\the\BKM@id\endcsname{%
              {\BKM@prev}{\BKM@level}%
            }%
            \BKM@swfalse
          \else
            \let\BKM@prev\BKM@x@parent
          \fi
        \fi
      }%
      \pdfstringdef\BKM@title{\bookmark@text}%
      \BKM@vtex@title
      \edef\BKM@FLAGS{\BKM@PrintStyle}%
      \let\BKM@action\@empty
      \ifx\BKM@gotor\@empty
        \ifx\BKM@dest\@empty
          \ifx\BKM@named\@empty
            \ifx\BKM@rawaction\@empty
              \ifx\BKM@uri\@empty
                \ifx\BKM@page\@empty
                  \PackageError{bookmark}{Missing action}\@ehc
                  \def\BKM@action{!1}%
                \else
                  \edef\BKM@action{!\BKM@page}%
                \fi
              \else
                \BKM@EscapeString\BKM@uri
                \edef\BKM@action{%
                  <u=%
                    /S/URI%
                    /URI(\BKM@uri)%
                  >%
                }%
              \fi
            \else
              \edef\BKM@action{<u=\BKM@rawaction>}%
            \fi
          \else
            \BKM@EscapeName\BKM@named
            \edef\BKM@action{%
              <u=%
                /S/Named%
                /N/\BKM@named
              >%
            }%
          \fi
        \else
          \BKM@EscapeString\BKM@dest
          \edef\BKM@action{\BKM@dest}%
        \fi
      \else
        \ifx\BKM@dest\@empty
          \ifx\BKM@page\@empty
            \def\BKM@page{1}%
          \fi
          \ifx\BKM@view\@empty
            \def\BKM@view{Fit}%
          \fi
          \edef\BKM@action{/D[\BKM@page/\BKM@view]}%
        \else
          \BKM@EscapeString\BKM@dest
          \edef\BKM@action{/D(\BKM@dest)}%
        \fi
        \BKM@EscapeString\BKM@gotor
        \edef\BKM@action{%
          <u=%
            /S/GoToR%
            /F(\BKM@gotor)%
            \BKM@action
          >>%
        }%
      \fi
      \ifx\BKM@color\@empty
        \let\BKM@RGBcolor\@empty
      \else
        \expandafter\BKM@toRGB\BKM@color\@nil
      \fi
      \special{%
        !outline \BKM@action;%
        p=\BKM@parent,%
        i=\number\BKM@id,%
        s=%
          \ifBKM@open
            \ifnum\BKM@level<\BKM@openlevel
              o%
            \else
              c%
            \fi
          \else
            c%
          \fi,%
        \ifx\BKM@RGBcolor\@empty
        \else
          c=\BKM@RGBcolor,%
        \fi
        \ifnum\BKM@FLAGS>\z@
          f=\BKM@FLAGS,%
        \fi
        t=\BKM@title
      }%
    \endgroup
  \fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\BKM@getx}
%    \begin{macrocode}
\def\BKM@getx#1#2{%
  \def\BKM@x@parent{#1}%
  \def\BKM@x@level{#2}%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\BKM@toRGB}
%    \begin{macrocode}
\def\BKM@toRGB#1 #2 #3\@nil{%
  \let\BKM@RGBcolor\@empty
  \BKM@toRGBComponent{#1}%
  \BKM@toRGBComponent{#2}%
  \BKM@toRGBComponent{#3}%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\BKM@toRGBComponent}
%    \begin{macrocode}
\def\BKM@toRGBComponent#1{%
  \dimen@=#1pt\relax
  \ifdim\dimen@>\z@
    \ifdim\dimen@<\p@
      \dimen@=255\dimen@
      \advance\dimen@ by 32768sp\relax
      \divide\dimen@ by 65536\relax
      \dimen@ii=\dimen@
      \divide\dimen@ii by 16\relax
      \edef\BKM@RGBcolor{%
        \BKM@RGBcolor
        \BKM@toHexDigit\dimen@ii
      }%
      \dimen@ii=16\dimen@ii
      \advance\dimen@-\dimen@ii
      \edef\BKM@RGBcolor{%
        \BKM@RGBcolor
        \BKM@toHexDigit\dimen@
      }%
    \else
      \edef\BKM@RGBcolor{\BKM@RGBcolor FF}%
    \fi
  \else
    \edef\BKM@RGBcolor{\BKM@RGBcolor00}%
  \fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\BKM@toHexDigit}
%    \begin{macrocode}
\def\BKM@toHexDigit#1{%
  \ifcase\expandafter\@firstofone\expandafter{\number#1} %
    0\or 1\or 2\or 3\or 4\or 5\or 6\or 7\or
    8\or 9\or A\or B\or C\or D\or E\or F%
  \fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
\begingroup
  \catcode`\|=0 %
  \catcode`\\=12 %
%    \end{macrocode}
%    \begin{macro}[int]{\BKM@vtex@title}
%    \begin{macrocode}
  |gdef|BKM@vtex@title{%
    |@onelevel@sanitize|BKM@title
    |edef|BKM@title{|expandafter|BKM@vtex@leftparen|BKM@title\(|@nil}%
    |edef|BKM@title{|expandafter|BKM@vtex@rightparen|BKM@title\)|@nil}%
    |edef|BKM@title{|expandafter|BKM@vtex@zero|BKM@title\0|@nil}%
    |edef|BKM@title{|expandafter|BKM@vtex@one|BKM@title\1|@nil}%
    |edef|BKM@title{|expandafter|BKM@vtex@two|BKM@title\2|@nil}%
    |edef|BKM@title{|expandafter|BKM@vtex@three|BKM@title\3|@nil}%
  }%
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\BKM@vtex@leftparen}
%    \begin{macrocode}
  |gdef|BKM@vtex@leftparen#1\(#2|@nil{%
    #1%
    |ifx||#2||%
    |else
      (%
      |BKM@ReturnAfterFi{%
        |BKM@vtex@leftparen#2|@nil
      }%
    |fi
  }%
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\BKM@vtex@rightparen}
%    \begin{macrocode}
  |gdef|BKM@vtex@rightparen#1\)#2|@nil{%
    #1%
    |ifx||#2||%
    |else
      )%
      |BKM@ReturnAfterFi{%
        |BKM@vtex@rightparen#2|@nil
      }%
    |fi
  }%
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\BKM@vtex@zero}
%    \begin{macrocode}
  |gdef|BKM@vtex@zero#1\0#2|@nil{%
    #1%
    |ifx||#2||%
    |else
      |noexpand|hv@pdf@char0%
      |BKM@ReturnAfterFi{%
        |BKM@vtex@zero#2|@nil
      }%
    |fi
  }%
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\BKM@vtex@one}
%    \begin{macrocode}
  |gdef|BKM@vtex@one#1\1#2|@nil{%
    #1%
    |ifx||#2||%
    |else
      |noexpand|hv@pdf@char1%
      |BKM@ReturnAfterFi{%
        |BKM@vtex@one#2|@nil
      }%
    |fi
  }%
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\BKM@vtex@two}
%    \begin{macrocode}
  |gdef|BKM@vtex@two#1\2#2|@nil{%
    #1%
    |ifx||#2||%
    |else
      |noexpand|hv@pdf@char2%
      |BKM@ReturnAfterFi{%
        |BKM@vtex@two#2|@nil
      }%
    |fi
  }%
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\BKM@vtex@three}
%    \begin{macrocode}
  |gdef|BKM@vtex@three#1\3#2|@nil{%
    #1%
    |ifx||#2||%
    |else
      |noexpand|hv@pdf@char3%
      |BKM@ReturnAfterFi{%
        |BKM@vtex@three#2|@nil
      }%
    |fi
  }%
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
|endgroup
%    \end{macrocode}
%
%    \begin{macrocode}
%</vtex>
%    \end{macrocode}
%
% \subsection{Driver for \hologo{pdfTeX}}
%
%    \begin{macrocode}
%<*pdftex>
\NeedsTeXFormat{LaTeX2e}
\ProvidesFile{bkm-pdftex.def}%
  [2026-05-21 v1.32 bookmark driver for pdfTeX (HO)]%
%</pdftex>  
%    \end{macrocode}
%    \begin{macrocode}
%<*luatex>
\NeedsTeXFormat{LaTeX2e}
\ProvidesFile{bkm-luatex.def}%
  [2026-05-21 v1.32 bookmark driver for luaTeX (HO)]%
%</luatex>  
%    \end{macrocode}
%
%    \begin{macrocode}
%<*pdftex|luatex>
%    \end{macrocode}
%
%    \begin{macro}[int]{\BKM@DO@entry}
%    \begin{macrocode}
\def\BKM@DO@entry#1#2{%
  \begingroup
    \SetKeys[BKM@DO]{#1}%
    \def\BKM@DO@title{#2}%
    \ifx\BKM@DO@srcfile\@empty
    \else
      \BKM@UnescapeHex\BKM@DO@srcfile
    \fi
    \BKM@UnescapeHex\BKM@DO@title
    \expandafter\expandafter\expandafter\BKM@getx
        \csname BKM@\BKM@DO@id\endcsname\@empty\@empty
    \let\BKM@attr\@empty
    \ifx\BKM@DO@flags\@empty
    \else
      \edef\BKM@attr{\BKM@attr/F \BKM@DO@flags}%
    \fi
    \ifx\BKM@DO@color\@empty
    \else
      \edef\BKM@attr{\BKM@attr/C[\BKM@DO@color]}%
    \fi
    \ifx\BKM@attr\@empty
    \else
      \edef\BKM@attr{attr{\BKM@attr}}%
    \fi
    \let\BKM@action\@empty
    \ifx\BKM@DO@gotor\@empty
      \ifx\BKM@DO@dest\@empty
        \ifx\BKM@DO@named\@empty
          \ifx\BKM@DO@rawaction\@empty
            \ifx\BKM@DO@uri\@empty
              \ifx\BKM@DO@page\@empty
                \PackageError{bookmark}{%
                  Missing action\BKM@SourceLocation
                }\@ehc
                \edef\BKM@action{goto page1{/Fit}}%
              \else
                \ifx\BKM@DO@view\@empty
                  \def\BKM@DO@view{Fit}%
                \fi
                \edef\BKM@action{goto page\BKM@DO@page{/\BKM@DO@view}}%
              \fi
            \else
              \BKM@UnescapeHex\BKM@DO@uri
              \BKM@EscapeString\BKM@DO@uri
              \edef\BKM@action{user{<</S/URI/URI(\BKM@DO@uri)>>}}%
            \fi
          \else
            \BKM@UnescapeHex\BKM@DO@rawaction
            \edef\BKM@action{%
              user{%
                <<%
                  \BKM@DO@rawaction
                >>%
              }%
            }%
          \fi
        \else
          \BKM@EscapeName\BKM@DO@named
          \edef\BKM@action{%
            user{<</S/Named/N/\BKM@DO@named>>}%
          }%
        \fi
      \else
        \BKM@UnescapeHex\BKM@DO@dest
        \BKM@DefGotoNameAction\BKM@action\BKM@DO@dest
      \fi
    \else
      \ifx\BKM@DO@dest\@empty
        \ifx\BKM@DO@page\@empty
          \def\BKM@DO@page{0}%
        \else
          \BKM@CalcExpr\BKM@DO@page\BKM@DO@page-1%
        \fi
        \ifx\BKM@DO@view\@empty
          \def\BKM@DO@view{Fit}%
        \fi
        \edef\BKM@action{/D[\BKM@DO@page/\BKM@DO@view]}%
      \else
        \BKM@UnescapeHex\BKM@DO@dest
        \BKM@EscapeString\BKM@DO@dest
        \edef\BKM@action{/D(\BKM@DO@dest)}%
      \fi
      \BKM@UnescapeHex\BKM@DO@gotor
      \BKM@EscapeString\BKM@DO@gotor
      \edef\BKM@action{%
        user{%
          <<%
            /S/GoToR%
            /F(\BKM@DO@gotor)%
            \BKM@action
          >>%
        }%
      }%
    \fi
%<pdftex>    \pdfoutline\BKM@attr\BKM@action
%<luatex>    \pdfextension outline\BKM@attr\BKM@action
                count\ifBKM@DO@open\else-\fi\BKM@x@childs
                {\BKM@DO@title}%
  \endgroup
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\BKM@DefGotoNameAction}
%    Macro \cs{BKM@DefGotoNameAction} is a hook for
%    package \xpackage{hypdestopt}.
%    \begin{macrocode}
  \def\BKM@DefGotoNameAction#1#2{%
    \BKM@EscapeString\BKM@DO@dest
    \edef#1{goto name{#2}}%
   }
%    \end{macrocode}
% If tagging is active we use also structure destinations.
% If hypdestopt is actually used this will be overwritten again.
%    \begin{macrocode}
\ExplSyntaxOn
\IfDocumentMetadataTF
 {
   \tag_if_active:T
     {
       \def\BKM@DefGotoNameAction#1#2
        {
         \BKM@EscapeString\BKM@DO@dest
         \edef#1{goto~struct~name~{#2}~name~{#2}}%
        }     
     }    
 }{} 
\ExplSyntaxOff
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
%</pdftex|luatex>
%    \end{macrocode}
%
%    \begin{macrocode}
%<*pdftex|luatex|pdfmark>
%    \end{macrocode}
%    \begin{macro}[int]{\BKM@SourceLocation}
%    \begin{macrocode}
\def\BKM@SourceLocation{%
  \ifx\BKM@DO@srcfile\@empty
    \ifx\BKM@DO@srcline\@empty
    \else
      .\MessageBreak
      Source: line \BKM@DO@srcline
    \fi
  \else
    \ifx\BKM@DO@srcline\@empty
      .\MessageBreak
      Source: file `\BKM@DO@srcfile'%
    \else
      .\MessageBreak
      Source: file `\BKM@DO@srcfile', line \BKM@DO@srcline
    \fi
  \fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
%</pdftex|luatex|pdfmark>
%    \end{macrocode}
%
% \subsection{Drivers with pdfmark specials}
%
% \subsubsection{Driver dvips}
% The dvips driver uses PSfile to include the bookmark to resolve a
% clash with pgf, see
% https://github.com/pgf-tikz/pgf/issues/944\#issuecomment-723099952
%    \begin{macrocode}
%<*dvips>
\NeedsTeXFormat{LaTeX2e}
\ProvidesFile{bkm-dvips.def}%
  [2026-05-21 v1.32 bookmark driver for dvips (HO)]%
%    \end{macrocode}
%    \begin{macro}[int]{\BKM@PSHeaderFile}
%    \begin{macrocode}
\def\BKM@PSHeaderFile#1{%
  \special{PSfile=#1}%
}
%    \end{macrocode}
%    \begin{macro}[int]{\BKM@filename}
%    \begin{macrocode}
\def\BKM@filename{\jobname.out.ps}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
\AddToHook{shipout/lastpage}{%
  \BKM@pdfmark@out
  \BKM@PSHeaderFile\BKM@filename
  }
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
%</dvips>
%    \end{macrocode}
%
% \subsubsection{Common part}
%
%    \begin{macrocode}
%<*pdfmark>
%    \end{macrocode}
%
%    \begin{macro}[int]{\BKM@pdfmark@out}
%    Do not use package \xpackage{rerunfilecheck} here, because
%    the file \cs{BKM@filename} is not read during the \hologo{TeX} run.
%    \begin{macrocode}
\def\BKM@pdfmark@out{%
  \if@filesw
    \newwrite\BKM@file
    \immediate\openout\BKM@file=\BKM@filename\relax
    \BKM@write{\@percentchar!}%
    \BKM@write{/pdfmark where{pop}}%
    \BKM@write{%
      {%
        /globaldict where{pop globaldict}{userdict}ifelse%
        /pdfmark/cleartomark load put%
      }%
    }%
    \BKM@write{ifelse}%
  \else
    \let\BKM@write\@gobble
    \let\BKM@DO@entry\@gobbletwo
  \fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\BKM@write}
%    \begin{macrocode}
\def\BKM@write#{%
  \immediate\write\BKM@file
}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}[int]{\BKM@DO@entry}
%    The specification for pdfmark says that |/Color| is the
%    name of the key for color, however ghostscript only passes
%    the key into the PDF file, thus the key name must be |/C|.
%    \begin{macrocode}
\def\BKM@DO@entry#1#2{%
  \begingroup
    \SetKeys[BKM@DO]{#1}%
    \ifx\BKM@DO@srcfile\@empty
    \else
      \BKM@UnescapeHex\BKM@DO@srcfile
    \fi
    \def\BKM@DO@title{#2}%
    \BKM@UnescapeHex\BKM@DO@title
    \expandafter\expandafter\expandafter\BKM@getx
        \csname BKM@\BKM@DO@id\endcsname\@empty\@empty
    \let\BKM@attr\@empty
    \ifx\BKM@DO@flags\@empty
    \else
      \edef\BKM@attr{\BKM@attr/F \BKM@DO@flags}%
    \fi
    \ifx\BKM@DO@color\@empty
    \else
      \edef\BKM@attr{\BKM@attr/C[\BKM@DO@color]}%
    \fi
    \let\BKM@action\@empty
    \ifx\BKM@DO@gotor\@empty
      \ifx\BKM@DO@dest\@empty
        \ifx\BKM@DO@named\@empty
          \ifx\BKM@DO@rawaction\@empty
            \ifx\BKM@DO@uri\@empty
              \ifx\BKM@DO@page\@empty
                \PackageError{bookmark}{%
                  Missing action\BKM@SourceLocation
                }\@ehc
                \edef\BKM@action{%
                  /Action/GoTo%
                  /Page 1%
                  /View[/Fit]%
                }%
              \else
                \ifx\BKM@DO@view\@empty
                  \def\BKM@DO@view{Fit}%
                \fi
                \edef\BKM@action{%
                  /Action/GoTo%
                  /Page \BKM@DO@page
                  /View[/\BKM@DO@view]%
                }%
              \fi
            \else
              \BKM@UnescapeHex\BKM@DO@uri
              \BKM@EscapeString\BKM@DO@uri
              \edef\BKM@action{%
                /Action<<%
                  /Subtype/URI%
                  /URI(\BKM@DO@uri)%
                >>%
              }%
            \fi
          \else
            \BKM@UnescapeHex\BKM@DO@rawaction
            \edef\BKM@action{%
              /Action<<%
                \BKM@DO@rawaction
              >>%
            }%
          \fi
        \else
          \BKM@EscapeName\BKM@DO@named
          \edef\BKM@action{%
            /Action<<%
              /Subtype/Named%
              /N/\BKM@DO@named
            >>%
          }%
        \fi
      \else
        \BKM@UnescapeHex\BKM@DO@dest
        \BKM@EscapeString\BKM@DO@dest
        \edef\BKM@action{%
          /Action/GoTo%
          /Dest(\BKM@DO@dest)cvn%
        }%
      \fi
    \else
      \ifx\BKM@DO@dest\@empty
        \ifx\BKM@DO@page\@empty
          \def\BKM@DO@page{1}%
        \fi
        \ifx\BKM@DO@view\@empty
          \def\BKM@DO@view{Fit}%
        \fi
        \edef\BKM@action{%
          /Page \BKM@DO@page
          /View[/\BKM@DO@view]%
        }%
      \else
        \BKM@UnescapeHex\BKM@DO@dest
        \BKM@EscapeString\BKM@DO@dest
        \edef\BKM@action{%
          /Dest(\BKM@DO@dest)cvn%
        }%
      \fi
      \BKM@UnescapeHex\BKM@DO@gotor
      \BKM@EscapeString\BKM@DO@gotor
      \edef\BKM@action{%
        /Action/GoToR%
        /File(\BKM@DO@gotor)%
        \BKM@action
      }%
    \fi
    \BKM@write{[}%
    \BKM@write{/Title(\BKM@DO@title)}%
    \ifnum\BKM@x@childs>\z@
      \BKM@write{/Count \ifBKM@DO@open\else-\fi\BKM@x@childs}%
    \fi
    \ifx\BKM@attr\@empty
    \else
      \BKM@write{\BKM@attr}%
    \fi
    \BKM@write{\BKM@action}%
    \BKM@write{/OUT pdfmark}%
  \endgroup
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
%</pdfmark>
%    \end{macrocode}
%
% \subsection{Common part for \xoption{pdftex} and \xoption{pdfmark}}
%
%    \begin{macrocode}
%<*pdftex|luatex|pdfmark>
%    \end{macrocode}
%
% \subsubsection{Write auxiliary file}
%
%    \begin{macrocode}
\AddToHook{begindocument}{%
 \immediate\write\@mainaux{\string\providecommand\string\BKM@entry[2]{}}}
%    \end{macrocode}
%
%    \begin{macro}[int]{\BKM@id}
%    \begin{macrocode}
\newcount\BKM@id
\BKM@id=\z@
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}[int]{\BKM@0}
%    \begin{macrocode}
\@namedef{BKM@0}{000}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\ifBKM@sw}
%    \begin{macrocode}
\newif\ifBKM@sw
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\bookmark}
%    \begin{macrocode}
\newcommand*{\bookmark}[2][]{%
  \if@filesw
    \begingroup
      \BKM@InitSourceLocation
      \def\bookmark@text{#2}%
      \BKM@setup{#1}%
      \ifx\BKM@srcfile\@empty
      \else
        \BKM@EscapeHex\BKM@srcfile
      \fi
      \edef\BKM@prev{\the\BKM@id}%
      \global\advance\BKM@id\@ne
      \BKM@swtrue
      \@whilesw\ifBKM@sw\fi{%
        \ifnum\ifBKM@startatroot\z@\else\BKM@prev\fi=\z@
          \BKM@startatrootfalse
          \expandafter\xdef\csname BKM@\the\BKM@id\endcsname{%
            0{\BKM@level}0%
          }%
          \BKM@swfalse
        \else
          \expandafter\expandafter\expandafter\BKM@getx
              \csname BKM@\BKM@prev\endcsname
          \ifnum\BKM@level>\BKM@x@level\relax
            \expandafter\xdef\csname BKM@\the\BKM@id\endcsname{%
              {\BKM@prev}{\BKM@level}0%
            }%
            \ifnum\BKM@prev>\z@
              \BKM@CalcExpr\BKM@CalcResult\BKM@x@childs+1%
              \expandafter\xdef\csname BKM@\BKM@prev\endcsname{%
                {\BKM@x@parent}{\BKM@x@level}{\BKM@CalcResult}%
              }%
            \fi
            \BKM@swfalse
          \else
            \let\BKM@prev\BKM@x@parent
          \fi
        \fi
      }%
      \pdfstringdef\BKM@title{\bookmark@text}%
      \edef\BKM@FLAGS{\BKM@PrintStyle}%
      \csname BKM@HypDestOptHook\endcsname
      \BKM@EscapeHex\BKM@dest
      \BKM@EscapeHex\BKM@uri
      \BKM@EscapeHex\BKM@gotor
      \BKM@EscapeHex\BKM@rawaction
      \BKM@EscapeHex\BKM@title
      \immediate\write\@mainaux{%
        \string\BKM@entry{%
          id=\number\BKM@id
          \ifBKM@open
            \ifnum\BKM@level<\BKM@openlevel
              ,open%
            \fi
          \fi
          \BKM@auxentry{dest}%
          \BKM@auxentry{named}%
          \BKM@auxentry{uri}%
          \BKM@auxentry{gotor}%
          \BKM@auxentry{page}%
          \BKM@auxentry{view}%
          \BKM@auxentry{rawaction}%
          \BKM@auxentry{color}%
          \ifnum\BKM@FLAGS>\z@
            ,flags=\BKM@FLAGS
          \fi
          \BKM@auxentry{srcline}%
          \BKM@auxentry{srcfile}%
        }{\BKM@title}%
      }%
    \endgroup
  \fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\BKM@getx}
%    \begin{macrocode}
\def\BKM@getx#1#2#3{%
  \def\BKM@x@parent{#1}%
  \def\BKM@x@level{#2}%
  \def\BKM@x@childs{#3}%
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\BKM@auxentry}
%    \begin{macrocode}
\def\BKM@auxentry#1{%
  \expandafter\ifx\csname BKM@#1\endcsname\@empty
  \else
    ,#1={\csname BKM@#1\endcsname}%
  \fi
}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}[int]{\BKM@InitSourceLocation}
%    \begin{macrocode}
\def\BKM@InitSourceLocation{%
  \edef\BKM@srcline{\the\inputlineno}%
  \BKM@LuaTeX@InitFile
  \ifx\BKM@srcfile\@empty
    \@ifundefined{currfilepath}{}{%
      \edef\BKM@srcfile{\currfilepath}%
    }%
  \fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}[int]{\BKM@LuaTeX@InitFile}
%    \begin{macrocode}
%<luatex>\def\BKM@LuaTeX@InitFile{%
%<luatex>  \begingroup
%<luatex>    \toks@={}%
%<luatex>  \edef\x{\endgroup
%<luatex>    \def\noexpand\BKM@srcfile{%
%<luatex>      \the\expandafter\toks@
%<luatex>      \directlua{%
%<luatex>         if status and status.filename then %
%<luatex>           tex.settoks('toks@', status.filename)%
%<luatex>         end%
%<luatex>      }%
%<luatex>    }%
%<luatex>  }\x
%<luatex>}%
%<pdftex|pdfmark>\let\BKM@LuaTeX@InitFile\relax

%    \end{macrocode}
%    \end{macro}
%
% \subsubsection{Read auxiliary data}
%
%    \begin{macrocode}
\DeclareKeys[BKM@DO]
 {
  ,id   .tl_set:N=\BKM@DO@id
  ,id   .initial:n = 0
  ,open .legacy_if_set:n = BKM@DO@open
  ,flags.tl_set:N=\BKM@DO@flags
  ,color.tl_set:N=\BKM@DO@color
  ,dest .tl_set:N=\BKM@DO@dest
  ,named.tl_set:N=\BKM@DO@named
  ,uri  .tl_set:N=\BKM@DO@uri
  ,gotor.tl_set:N=\BKM@DO@gotor
  ,page .tl_set:N=\BKM@DO@page
  ,view .tl_set:N=\BKM@DO@view
  ,rawaction.tl_set:N=\BKM@DO@rawaction
  ,srcline.tl_set:N=\BKM@DO@srcline
  ,srcfile.tl_set:N=\BKM@DO@srcfile
 }
%    \end{macrocode}
%
%    \begin{macrocode}
\AtBeginDocument{%
  \let\BKM@entry\BKM@DO@entry
}
%    \end{macrocode}
%
%    \begin{macrocode}
%</pdftex|luatex|pdfmark>
%    \end{macrocode}
%
% \subsection{Option \xoption{atend}}
%
% \subsubsection{Hook}
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%    \begin{macrocode}
\ifBKM@atend
\else
%    \end{macrocode}
%    \begin{macro}{\BookmarkAtEnd}
%    This is a dummy definition that generates a warning
%    if option \xoption{atend} has not been given.
%    \begin{macrocode}
  \newcommand{\BookmarkAtEnd}[1]{%
    \PackageWarning{bookmark}{%
      Ignored, because option `atend' is missing%
    }%
  }%
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
  \expandafter\endinput
\fi
%    \end{macrocode}
%    \begin{macro}{\BookmarkAtEnd}
%    \begin{macrocode}
\newcommand*{\BookmarkAtEnd}{%
  \g@addto@macro\BKM@EndHook
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
\let\BKM@EndHook\@empty
%    \end{macrocode}
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \subsubsection{Drivers using hooks at end of document}
%
%    Driver \xoption{pdftex} use the LaTeX hook \hook{enddocument/afterlastpage}
%    (which is equivalent to the previously used
%    \cs{AfterLastShipout} of \xpackage{atveryend}'s),
%    because it still needs the \xext{aux} file. It uses
%    \cs{pdfoutline} for the bookmarks that can  be used after the last page.
%    \begin{itemize}
%    \item
%      Driver \xoption{pdftex} uses \cs{pdfoutline} that can
%      be used after the last page.
%    \end{itemize}
%    \begin{macrocode}
%<*pdftex|luatex>
\ifBKM@atend
  \AddToHook{enddocument/afterlastpage}{%
    \BKM@EndHook
  }%
\fi
%</pdftex|luatex>
%    \end{macrocode}
%
% \subsubsection{Drivers using \hook{shipout/lastpage}}
%
%    The other drivers implement \cs{bookmark} using \cs{special}
%    commands. Thus the last bookmarks must be put on the last page,
%    not afterwards.
%    \cs{AtEndDocument} cannot be used, because it is too late, the
%    last page can already be output. Therefore we use the
%    LaTeX hook \hook{shipout/lastpage}.
%    At least two \hologo{LaTeX} runs are necessary.
%    The postscript driver \xoption{dvips} use an external PostScript file
%    for the bookmarks. The file writing has been moved to the
%    the last shipout page too to avoid conflicts with pgf.
%    \begin{macrocode}
%<*dvipdfmx|xetex|vtex|pdfmark>
\ifBKM@atend
  \AddToHook{shipout/lastpage}{\BKM@EndHook}%
\fi
%</dvipdfmx|xetex|vtex|pdfmark>
%    \end{macrocode}
%
% \section{Installation}
%
% \subsection{Download}
%
% \paragraph{Package.} This package is available on
% CTAN\footnote{\CTANpkg{bookmark}}:
% \begin{description}
% \item[\CTAN{macros/latex/contrib/bookmark/bookmark.dtx}] The source file.
% \item[\CTAN{macros/latex/contrib/bookmark/bookmark.ins}] Installation driver.
% \item[\CTAN{macros/latex/contrib/bookmark/bookmark.pdf}] Documentation.
% \end{description}
%
% \subsection{Package installation}
%
% The easiest is to use the package manager from your TeX system. If
% you want to install manually:
% 
% \paragraph{Unpacking.} The \xfile{.dtx} file is 
% \docstrip\ archive. The files are extracted from the \xfile{.dtx}
% by compiling the file with some TeX program.
% \begin{quote}
%   \verb|pdflatex bookmark.dtx|
% \end{quote}
%
% \paragraph{TDS.} Now the different files must be moved into
% the different directories in your installation TDS tree
% (also known as \xfile{texmf} tree):
% \begin{quote}
% \begin{tabular}{@{}>{\ttfamily}l@{ $\rightarrow$ }>{\ttfamily}l@{}}
%   bookmark.sty & tex/latex/bookmark/bookmark.sty\\
%   bkm-dvipdfmx.def & tex/latex/bookmark/bkm-dvipdfmx.def\\
%   bkm-dvips.def & tex/latex/bookmark/bkm-dvips.def\\
%   bkm-pdftex.def & tex/latex/bookmark/bkm-pdftex.def\\
%   bkm-luatex.def & tex/latex/bookmark/bkm-luatex.def\\
%   bkm-xetex.def & tex/latex/bookmark/bkm-xetex.def\\   
%   bkm-vtex.def & tex/latex/bookmark/bkm-vtex.def\\
%   bookmark.pdf & doc/latex/bookmark/bookmark.pdf\\
%   bookmark-example.tex & doc/latex/bookmark/bookmark-example.tex\\
%   bookmark.dtx & source/latex/bookmark/bookmark.dtx\\
% \end{tabular}
% \end{quote}
% If you have a \xfile{docstrip.cfg} that configures and enables \docstrip's
% TDS installing feature, then some files can already be in the right
% place, see the documentation of \docstrip.
%
% \subsection{Refresh file name databases}
%
% If your \TeX~distribution
% (\hologo{TeXLive}, \hologo{MiKTeX}, \dots) relies on file name databases, you must refresh
% these. For example, \hologo{TeXLive}\ users run \verb|texhash| or
% \verb|mktexlsr|.
%
% \paragraph{Generating the documentation.}
% You can use the \xfile{.dtx} to generate
% the documentation. As the documentation is now tagged, 
% lua\LaTeX\ should be used and a current \TeX-system is required.
% \begin{quote}
%\begin{verbatim}
% lualatex bookmark.dtx
% makeindex -s gind.ist bookmark.idx
% lualatex bookmark.dtx
% lualatex bookmark.dtx
% lualatex bookmark.dtx
%\end{verbatim}
% \end{quote}
%
% \begin{thebibliography}{9}
%
% \bibitem{hyperref}
%   Sebastian Rahtz, Heiko Oberdiek, The \LaTeX\ project:
%   \textit{The \xpackage{hyperref} package};
%   2026-04-24 v7.01q;
%   \CTANpkg{hyperref}
%
% \bibitem{currfile}
%   Martin Scharrer:
%   \textit{The \xpackage{currfile} package};
%   2024/03/14 v1.0.
%   \CTANpkg{currfile}
%
% \end{thebibliography}
%
% \begin{History}
%   \begin{Version}{2007/02/19 v0.1}
%   \item
%     First experimental version.
%   \end{Version}
%   \begin{Version}{2007/02/20 v0.2}
%   \item
%     Option \xoption{startatroot} added.
%   \item
%     Dummies for \cs{pdf(un)escape...} commands added to get
%     the package basically work for non-\hologo{pdfTeX} users.
%   \end{Version}
%   \begin{Version}{2007/02/21 v0.3}
%   \item
%     Dependency from \hologo{pdfTeX} 1.30 removed by using package
%     \xpackage{pdfescape}.
%   \end{Version}
%   \begin{Version}{2007/02/22 v0.4}
%   \item
%     \xpackage{hyperref}'s \xoption{bookmarkstype} respected.
%   \end{Version}
%   \begin{Version}{2007/03/02 v0.5}
%   \item
%     Driver options \xoption{vtex} (PDF mode), \xoption{dvipsone},
%     and \xoption{textures} added.
%   \item
%     Implementation of option \xoption{depth} completed. Division names
%     are supported, see \xpackage{hyperref}'s
%     option \xoption{bookmarksdepth}.
%   \item
%     \xpackage{hyperref}'s options \xoption{bookmarksopen},
%     \xoption{bookmarksopenlevel}, and \xoption{bookmarksdepth} respected.
%   \end{Version}
%   \begin{Version}{2007/03/03 v0.6}
%   \item
%     Option \xoption{numbered} as alias for \xpackage{hyperref}'s
%     \xoption{bookmarksnumbered}.
%   \end{Version}
%   \begin{Version}{2007/03/07 v0.7}
%   \item
%     Dependency from \hologo{eTeX} removed.
%   \end{Version}
%   \begin{Version}{2007/04/09 v0.8}
%   \item
%     Option \xoption{atend} added.
%   \item
%     Option \xoption{rgbcolor} removed.
%     \verb|rgbcolor=<r> <g> <b>| can be replaced by
%     \verb|color=[rgb]{<r>,<g>,<b>}|.
%   \item
%     Support of recent cvs version (2007-03-29) of dvipdfmx
%     that extends the \cs{special} for bookmarks to specify
%     open outline entries. Option \xoption{dvipdfmx-outline-open}
%     or \cs{SpecialDvipdfmxOutlineOpen} notify the package.
%   \end{Version}
%   \begin{Version}{2007/04/25 v0.9}
%   \item
%     The syntax of \cs{special} of dvipdfmx, if feature
%     \xoption{dvipdfmx-outline-open} is enabled, has changed.
%     Now cvs version 2007-04-25 is needed.
%   \end{Version}
%   \begin{Version}{2007/05/29 v1.0}
%   \item
%     Bug fix in code for second parameter of XYZ.
%   \end{Version}
%   \begin{Version}{2007/07/13 v1.1}
%   \item
%     Fix for pdfmark with GoToR action.
%   \end{Version}
%   \begin{Version}{2007/09/25 v1.2}
%   \item
%     pdfmark driver respects \cs{nofiles}.
%   \end{Version}
%   \begin{Version}{2008/08/08 v1.3}
%   \item
%     Package \xpackage{flags} replaced by package \xpackage{bitset}.
%     Now flags are also supported without \hologo{eTeX}.
%   \item
%     Hook for package \xpackage{hypdestopt} added.
%   \end{Version}
%   \begin{Version}{2008/09/13 v1.4}
%   \item
%     Fix for bug introduced in v1.3, package \xpackage{flags} is one-based,
%     but package \xpackage{bitset} is zero-based. Thus options \xoption{bold}
%     and \xoption{italic} are wrong in v1.3. (Daniel M\"ullner)
%   \end{Version}
%   \begin{Version}{2009/08/13 v1.5}
%   \item
%     Except for driver options the other options are now local options.
%     This resolves a problem with KOMA-Script v3.00 and its option \xoption{open}.
%   \end{Version}
%   \begin{Version}{2009/12/06 v1.6}
%   \item
%     Use of package \xpackage{atveryend} for drivers \xoption{pdftex}
%     and \xoption{pdfmark}.
%   \end{Version}
%   \begin{Version}{2009/12/07 v1.7}
%   \item
%     Use of package \xpackage{atveryend} fixed.
%   \end{Version}
%   \begin{Version}{2009/12/17 v1.8}
%   \item
%     Support of \xpackage{hyperref} 2009/12/17 v6.79v for \hologo{XeTeX}.
%   \end{Version}
%   \begin{Version}{2010/03/30 v1.9}
%   \item
%     Package name in an error message fixed.
%   \end{Version}
%   \begin{Version}{2010/04/03 v1.10}
%   \item
%     Option \xoption{style} and macro \cs{bookmarkdefinestyle} added.
%   \item
%     Hook support with option \xoption{addtohook} added.
%   \item
%     \cs{bookmarkget} added.
%   \end{Version}
%   \begin{Version}{2010/04/04 v1.11}
%   \item
%     Bug fix (introduced in v1.10).
%   \end{Version}
%   \begin{Version}{2010/04/08 v1.12}
%   \item
%     Requires \xpackage{ltxcmds} 2010/04/08.
%   \end{Version}
%   \begin{Version}{2010/07/23 v1.13}
%   \item
%     Support for \xclass{memoir}'s \cs{booknumberline} added.
%   \end{Version}
%   \begin{Version}{2010/09/02 v1.14}
%   \item
%     (Local) options \xoption{draft} and \xoption{final} added.
%   \end{Version}
%   \begin{Version}{2010/09/25 v1.15}
%   \item
%     Fix for option \xoption{dvipdfmx-outline-open}.
%   \item
%     Option \xoption{dvipdfmx-outline-open} is set automatically,
%     if XeTeX $\geq$ 0.9995 is detected.
%   \end{Version}
%   \begin{Version}{2010/10/19 v1.16}
%   \item
%     Option `startatroot' now acts globally.
%   \item
%     Option `level' also accepts names the same way as option `depth'.
%   \end{Version}
%   \begin{Version}{2010/10/25 v1.17}
%   \item
%     \cs{bookmarksetupnext} added.
%   \item
%     Using \cs{kvsetkeys} of package \xpackage{kvsetkeys}, because
%     \cs{setkeys} of package \xpackage{keyval} is not reentrant.
%     This can cause problems (unknown keys) with older versions of
%     hyperref that also uses \cs{setkeys} (found by GL).
%   \end{Version}
%   \begin{Version}{2010/11/05 v1.18}
%   \item
%     Use of \cs{pdf@ifdraftmode} of package \xpackage{pdftexcmds} for
%     the default of option \xoption{draft}.
%   \end{Version}
%   \begin{Version}{2011/03/20 v1.19}
%   \item
%     Use of \cs{dimexpr} fixed, if \hologo{eTeX} is not used.
%     (Bug found by Martin M\"unch.)
%   \item
%     Fix in documentation. Also layout options work without \hologo{eTeX}.
%   \end{Version}
%   \begin{Version}{2011/04/13 v1.20}
%   \item
%     Bug fix: \cs{BKM@SetDepth} renamed to \cs{BKM@SetDepthOrLevel}.
%   \end{Version}
%   \begin{Version}{2011/04/21 v1.21}
%   \item
%     Some support for file name and line number in error messages
%     at end of document (pdfTeX and pdfmark based drivers).
%   \end{Version}
%   \begin{Version}{2011/05/13 v1.22}
%   \item
%     Change of version 2010/11/05 v1.18 reverted, because otherwise
%     draftmode disables some \xext{aux} file entries.
%   \end{Version}
%   \begin{Version}{2011/09/19 v1.23}
%   \item
%     Some \cs{renewcommand}s changed to \cs{def} to avoid trouble
%     if the commands are not defined, because hyperref stopped early.
%   \end{Version}
%   \begin{Version}{2011/12/02 v1.24}
%   \item
%     Small optimization in \cs{BKM@toHexDigit}.
%   \end{Version}
%   \begin{Version}{2016/05/16 v1.25}
%   \item
%     Documentation updates.
%   \end{Version}
%   \begin{Version}{2016/05/17 v1.26}
%   \item
%     define \cs{pdfoutline} to allow pdftex driver to be used with Lua\TeX.
%   \end{Version}
%   \begin{Version}{2019/06/04 v1.27}
%   \item
%     unknown style options are ignored (issue 67)
%   \end{Version}

%   \begin{Version}{2019/12/03 v1.28}
%   \item
%     Documentation updates.
%   \item adjust package loading (all required packages already loaded
%     by \xpackage{hyperref}).
%   \end{Version}
%   \begin{Version}{2020-11-06 v1.29}
%   \item Adapted the dvips to avoid a clash with pgf.
%         https://github.com/pgf-tikz/pgf/issues/944
%   \item All drivers now use the new LaTeX hooks
%         and so require a format 2020-10-01 or newer.
%   \item Added support for destlabel option of hyperref, https://github.com/ho-tex/bookmark/issues/1
%   \item Removed the \xoption{dvipsone} and \xoption{textures} driver.
%   \item Removed the code for option \xoption{dvipdfmx-outline-open}
%     and \cs{SpecialDvipdfmxOutlineOpen}. All dvipdfmx version should now support
%     this out-of-the-box.
%   \end{Version}
%   \begin{Version}{2023-12-05 v1.30}
%   \item Corrected support for option \xoption{bookmarkstype} of
%   \xpackage{hyperref}, https://github.com/ho-tex/bookmark/issues/4
%   \item Added support for structure destinations, https://github.com/ho-tex/bookmark/issues/7   
%   \end{Version}
%   \begin{Version}{2023-12-10 v1.31}
%   \item Simplified the \xfile{.dtx}. It is no longer a self-extracting archive
%    instead the newly added \xfile{.ins} should be used for installation.
%    https://github.com/ho-tex/bookmark/issues/7
%   \item Removed the now outdated frozen drivers. 
%   \item Removed the dependency to ltxcmds. 
%   \end{Version}
%   \begin{Version}{2026-05-21 v1.32}
%   \item Driver options are now obsolete. The backend is detected automatically.
%   \item Driver files have been renamed to follow the LaTeX kernel.
%   \item The package uses now the LaTeX key-value system for the options to avoid
%   option clash errors.
%   \item The documentation is now tagged.
%   \end{Version}
% \end{History}
%
% \PrintIndex
%
% \Finale
\endinput
