% \iffalse meta-comment % % File: bookmark.dtx % Version: 2023-12-10 v1.31 % Info: PDF bookmarks % % Copyright (C) % 2007-2011 Heiko Oberdiek % 2016-2023 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> \NeedsTeXFormat{LaTeX2e} \ProvidesFile{bookmark.drv}% [2023-12-10 v1.31 PDF bookmarks (HO)]% \documentclass{ltxdoc} \usepackage{holtxdoc}[2011/11/22] \begin{document} \DocInput{bookmark.dtx}% \end{document} % % \fi % % % \title{The \xpackage{bookmark} package} % \date{2023-12-10 v1.31} % \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} % % 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. % % \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} % % Supported drivers are \xoption{pdftex}, \xoption{dvips}, % \xoption{dvipdfmx} (\xoption{xetex} and older name % \xoption{dvipdfm}), and \xoption{vtex}. % The \hologo{TeX} engines \hologo{pdfTeX}, \hologo{XeTeX}, % and \hologo{VTeX} are automatically detected. % The default for the DVI drivers is \xoption{dvips}. This can % be changed in the configuration file \xfile{bookmark.cfg} by % \cs{BookmarkDriverDefault}, e.g.: % \begin{quote} % |\def\BookmarkDriverDefault{dvipdfm}| % \end{quote} % The current versions of the drivers uses new \LaTeX-hooks and tests if the PDF management % is active and so requires 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. % Without package \xpackage{xcolor} the recognized values % are restricted to % \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}| % \end{itemize} % Note that this restriction also holds if package \xpackage{color} % is loaded. With \xpackage{xcolor}, however, the full range % of color specifications can be used. % \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{declcs}{bookmarkdefinestyle} \M{name} \M{key value list} % \end{declcs} % The \meta{key value list} of option settings is assigned the % style \meta{name}. % % \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{declcs}{bookmarkget} \M{option} % \end{declcs} % 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{quote} % \cs{pdfbookmark}\\ % \cs{currentpdfbookmark}\\ % \cs{subpdfbookmark}\\ % \cs{belowpdfbookmark} % \end{quote} % % \subsection{Adding bookmarks at the end} % % Package option \xoption{atend} enables the following macro: % \begin{declcs}{BookmarkAtEnd} % \M{stuff} % \end{declcs} % 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} % use package \xpackage{atveryend}'s % for this purpose. \cs{AtEndDocument} is too early, % the last page might not been shipped out. Because the \xext{aux} % file is needed, this driver use \cs{AfterLastShipout}. % % The implementation of the other drivers % (\xoption{dvipdfm}, \xoption{xetex}, \xoption{vtex}) % depends on % \cs{special} that does not have an effect after the last % page. In this case \cs{AtEndDvi} of package \xpackage{atenddvi} % helps. It puts its argument on last page of the document. % Two \hologo{LaTeX} runs are necessary at least, because % the last page is detected by a reference. % % \xoption{dvips} uses now the new LaTeX hook \texttt{shipout/lastpage}. % \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 e.g. % \begin{verbatim} % \DocumentMetadata{testphase=phase-III} %or some other phase a % \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 pdftex, luatex and % xetex/dvipdfmx. % % % \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} % % \end{macrocode} % % \StopEventually{ % } % % \section{Implementation} % % \subsection{Package} % % \begin{macrocode} %<*package> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{bookmark}% [2023-12-10 v1.31 PDF bookmarks (HO)]% % \end{macrocode} % % \subsubsection{Requirements} % % \paragraph{\hologo{eTeX}.} % % \begin{macro}{\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}{\BKM@EscapeName} % \begin{macrocode} \def\BKM@EscapeName#1{% \ifx#1\@empty \else \EdefEscapeName#1#1% \fi }% % \end{macrocode} % \end{macro} % \begin{macro}{\BKM@EscapeString} % \begin{macrocode} \def\BKM@EscapeString#1{% \ifx#1\@empty \else \EdefEscapeString#1#1% \fi }% % \end{macrocode} % \end{macro} % \begin{macro}{\BKM@EscapeHex} % \begin{macrocode} \def\BKM@EscapeHex#1{% \ifx#1\@empty \else \EdefEscapeHex#1#1% \fi }% % \end{macrocode} % \end{macro} % \begin{macro}{\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}{\BKM@ReturnAfterFi} % \begin{macro}{\BKM@space} % \begin{macro}{\BKM@GlobalAppendToMacro} % \begin{macro}{\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} \SetupKeyvalOptions{family=BKM,prefix=BKM@} \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}{\kvsetkeys{BKM}} % \end{macrocode} % \end{macro} % \begin{macro}{\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}{\BKM@setupnext} % \begin{macrocode} % \end{macrocode} % \end{macro} % \begin{macro}{\BKM@HookNextClear} % \begin{macrocode} \def\BKM@HookNextClear{% \global\let\BKM@HookNext\@empty } % \end{macrocode} % \end{macro} % \begin{macro}{\BKM@HookNext} % \begin{macrocode} \BKM@HookNextClear % \end{macrocode} % \end{macro} % % \begin{macrocode} \DeclareBoolOption{draft} \DeclareComplementaryOption{final}{draft} % \end{macrocode} % \begin{macro}{\BKM@DisableOptions} % \begin{macrocode} \def\BKM@DisableOptions{% \DisableKeyvalOption[action=warning,package=bookmark]% {BKM}{draft}% \DisableKeyvalOption[action=warning,package=bookmark]% {BKM}{final}% } % \end{macrocode} % \end{macro} % \begin{macrocode} \DeclareBoolOption[\ifHy@bookmarksopen true\else false\fi]{open} % \end{macrocode} % \begin{macro}{\bookmark@open} % \begin{macrocode} \def\bookmark@open{% \ifBKM@open\@ne\else\z@\fi } % \end{macrocode} % \end{macro} % \begin{macrocode} \DeclareStringOption[\maxdimen]{openlevel} % \end{macrocode} % \begin{macro}{\BKM@openlevel} % \begin{macrocode} \edef\BKM@openlevel{\number\@bookmarksopenlevel} % \end{macrocode} % \end{macro} % \begin{macrocode} %\DeclareStringOption[\c@tocdepth]{depth} \@ifundefined{Hy@bookmarksdepth}{% \def\BKM@depth{\c@tocdepth}% }{% \let\BKM@depth\Hy@bookmarksdepth } \define@key{BKM}{depth}[]{% \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} % \begin{macro}{\bookmark@depth} % \begin{macrocode} \def\bookmark@depth{\BKM@depth} % \end{macrocode} % \end{macro} % \begin{macro}{\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{macrocode} \DeclareStringOption[\BKM@currentlevel]{level}[\BKM@currentlevel] \define@key{BKM}{level}{% \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} % \begin{macro}{\BKM@MacroCurrentLevel} % \begin{macrocode} \def\BKM@MacroCurrentLevel{\BKM@currentlevel} % \end{macrocode} % \end{macro} % \begin{macrocode} \DeclareBoolOption{keeplevel} \DeclareBoolOption{startatroot} % \end{macrocode} % \begin{macro}{\BKM@startatrootfalse} % \begin{macrocode} \def\BKM@startatrootfalse{% \global\let\ifBKM@startatroot\iffalse } % \end{macrocode} % \end{macro} % \begin{macro}{\BKM@startatroottrue} % \begin{macrocode} \def\BKM@startatroottrue{% \global\let\ifBKM@startatroot\iftrue } % \end{macrocode} % \end{macro} % \begin{macrocode} \define@key{BKM}{rellevel}{% \BKM@CalcExpr\BKM@level{#1}+\BKM@currentlevel } % \end{macrocode} % \begin{macro}{\bookmark@level} % \begin{macrocode} \def\bookmark@level{\BKM@level} % \end{macrocode} % \end{macro} % \begin{macro}{\BKM@currentlevel} % \begin{macrocode} \def\BKM@currentlevel{0} % \end{macrocode} % \end{macro} % Make \xpackage{bookmark}'s option \xoption{numbered} an alias % for \xpackage{hyperref}'s \xoption{bookmarksnumbered}. % \begin{macrocode} \DeclareBoolOption[% \ifHy@bookmarksnumbered true\else false\fi ]{numbered} \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} % \begin{macro}{\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}{\BKM@PatchHyperrefOption} % \begin{macrocode} \def\BKM@PatchHyperrefOption#1{% \expandafter\BKM@@PatchHyperrefOption\csname KV@Hyp@#1\endcsname% } % \end{macrocode} % \end{macro} % \begin{macro}{\BKM@@PatchHyperrefOption} % \begin{macrocode} \def\BKM@@PatchHyperrefOption#1{% \expandafter\BKM@@@PatchHyperrefOption#1{##1}\BKM@nil#1% } % \end{macrocode} % \end{macro} % \begin{macro}{\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{macrocode} \bitsetReset{BKM@FontStyle}% \define@key{BKM}{italic}[true]{% \expandafter\ifx\csname if#1\endcsname\iftrue \bitsetSet{BKM@FontStyle}{0}% \else \bitsetClear{BKM@FontStyle}{0}% \fi }% \define@key{BKM}{bold}[true]{% \expandafter\ifx\csname if#1\endcsname\iftrue \bitsetSet{BKM@FontStyle}{1}% \else \bitsetClear{BKM@FontStyle}{1}% \fi }% % \end{macrocode} % \begin{macro}{\bookmark@italic} % \begin{macrocode} \def\bookmark@italic{% \ifnum\bitsetGet{BKM@FontStyle}{0}=1 \@ne\else\z@\fi } % \end{macrocode} % \end{macro} % \begin{macro}{\bookmark@bold} % \begin{macrocode} \def\bookmark@bold{% \ifnum\bitsetGet{BKM@FontStyle}{1}=1 \@ne\else\z@\fi } % \end{macrocode} % \end{macro} % \begin{macro}{\BKM@PrintStyle} % \begin{macrocode} \def\BKM@PrintStyle{% \bitsetGetDec{BKM@FontStyle}% }% % \end{macrocode} % \end{macro} % % \paragraph{Options for color.} % % \begin{macrocode} \define@key{BKM}{color}{% \HyColor@BookmarkColor{#1}\BKM@color{bookmark}{color}% } % \end{macrocode} % \begin{macro}{\BKM@color} % \begin{macrocode} \let\BKM@color\@empty % \end{macrocode} % \end{macro} % \begin{macro}{\bookmark@color} % \begin{macrocode} \def\bookmark@color{\BKM@color} % \end{macrocode} % \end{macro} % % \subsubsection{Action options} % % \begin{macrocode} \def\BKM@temp#1{% \DeclareStringOption{#1}% \expandafter\edef\csname bookmark@#1\endcsname{% \expandafter\noexpand\csname BKM@#1\endcsname }% } % \end{macrocode} % \begin{macro}{\bookmark@dest} % \begin{macrocode} \BKM@temp{dest} % \end{macrocode} % \end{macro} % \begin{macro}{\bookmark@named} % \begin{macrocode} \BKM@temp{named} % \end{macrocode} % \end{macro} % \begin{macro}{\bookmark@uri} % \begin{macrocode} \BKM@temp{uri} % \end{macrocode} % \end{macro} % \begin{macro}{\bookmark@gotor} % \begin{macrocode} \BKM@temp{gotor} % \end{macrocode} % \end{macro} % \begin{macro}{\bookmark@rawaction} % \begin{macrocode} \BKM@temp{rawaction} % \end{macrocode} % \end{macro} % % \begin{macrocode} \define@key{BKM}{page}{% \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} % \begin{macro}{\BKM@page} % \begin{macrocode} \let\BKM@page\@empty % \end{macrocode} % \end{macro} % \begin{macro}{\bookmark@page} % \begin{macrocode} \def\bookmark@page{\BKM@@page} % \end{macrocode} % \end{macro} % % \begin{macrocode} \define@key{BKM}{view}{% \BKM@CheckView{#1}% } % \end{macrocode} % \begin{macro}{\BKM@view} % \begin{macrocode} \let\BKM@view\@empty % \end{macrocode} % \end{macro} % \begin{macro}{\bookmark@view} % \begin{macrocode} \def\bookmark@view{\BKM@view} % \end{macrocode} % \end{macro} % \begin{macro}{BKM@CheckView} % \begin{macrocode} \def\BKM@CheckView#1{% \BKM@CheckViewType#1 \@nil } % \end{macrocode} % \end{macro} % \begin{macro}{\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}{\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}{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}{BKM@CheckRect} % \begin{macrocode} \def\BKM@CheckRect#1#2{% \BKM@@CheckRect#1#2#2#2#2\@nil } % \end{macrocode} % \end{macro} % \begin{macro}{\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}{\BKM@CheckXYZ} % \begin{macrocode} \def\BKM@CheckXYZ#1#2{% \BKM@@CheckXYZ#1#2#2#2\@nil } % \end{macrocode} % \end{macro} % \begin{macro}{\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}{\BKM@null} % \begin{macrocode} \def\BKM@null{null} \@onelevel@sanitize\BKM@null % \end{macrocode} % \end{macro} % % \begin{macro}{\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}{\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{macrocode} \DeclareBoolOption{atend} \g@addto@macro\BKM@DisableOptions{% \DisableKeyvalOption[action=warning,package=bookmark]% {BKM}{atend}% } % \end{macrocode} % % \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{macrocode} \define@key{BKM}{style}{% \BKM@StyleCall{#1}% } \newif\ifBKM@ok % \end{macrocode} % \begin{macro}{\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}{\BKM@StyleStackPop} % \begin{macrocode} \def\BKM@StyleStackPop{% \let\BKM@StyleEntry\relax \edef\BKM@StyleStack{% \expandafter\@gobbletwo\BKM@StyleStack }% } % \end{macrocode} % \end{macro} % \begin{macro}{\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}{\BKM@StyleStack} % \begin{macrocode} \def\BKM@StyleStack{} % \end{macrocode} % \end{macro} % % \subsubsection{Options for source file location} % % \begin{macrocode} \DeclareStringOption{srcline} \DeclareStringOption{srcfile} % \end{macrocode} % % \subsubsection{Hook support} % % \begin{macro}{\BKM@hook} % \begin{macrocode} \def\BKM@hook{} % \end{macrocode} % \end{macro} % \begin{macrocode} \define@key{BKM}{addtohook}{% \BKM@LocalAppendToMacro\BKM@hook{#1}% } % \end{macrocode} % % \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}{\BKM@DefineDriverKey} % \begin{macrocode} \def\BKM@DefineDriverKey#1{% \define@key{BKM}{#1}[]{% \def\BKM@driver{#1}% }% \g@addto@macro\BKM@DisableOptions{% \DisableKeyvalOption[action=warning,package=bookmark]% {BKM}{#1}% }% } % \end{macrocode} % \end{macro} % \begin{macrocode} \BKM@DefineDriverKey{pdftex} \BKM@DefineDriverKey{dvips} \BKM@DefineDriverKey{dvipdfm} \BKM@DefineDriverKey{dvipdfmx} \BKM@DefineDriverKey{xetex} \BKM@DefineDriverKey{vtex} \define@key{BKM}{dvipdfmx-outline-open}[true]{% \PackageWarning{bookmark}{Option 'dvipdfmx-outline-open' is obsolete and ignored}{}} % \end{macrocode} % \begin{macro}{\bookmark@driver} % \begin{macrocode} \def\bookmark@driver{\BKM@driver} % \end{macrocode} % \end{macro} % \begin{macrocode} \InputIfFileExists{bookmark.cfg}{}{} % \end{macrocode} % \begin{macro}{\BookmarkDriverDefault} % \begin{macrocode} \providecommand*{\BookmarkDriverDefault}{dvips} % \end{macrocode} % \end{macro} % \begin{macro}{\BKM@driver} % Lua\TeX\ and pdf\TeX\ share driver. % \begin{macrocode} \ifpdf \def\BKM@driver{pdftex}% \ifx\pdfoutline\@undefined \ifx\pdfextension\@undefined\else \protected\def\pdfoutline{\pdfextension outline } \fi \fi \else \ifxetex \def\BKM@driver{dvipdfm}% \else \ifvtex \def\BKM@driver{vtex}% \else \edef\BKM@driver{\BookmarkDriverDefault}% \fi \fi \fi % \end{macrocode} % \end{macro} % % \paragraph{Process options.} % % \begin{macrocode} \ProcessKeyvalOptions* \BKM@DisableOptions % \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 validation and loading.} % % \begin{macrocode} \def\BKM@temp{dvipdfmx}% \ifx\BKM@temp\BKM@driver \def\BKM@driver{dvipdfm}% \fi \def\BKM@temp{pdftex}% \ifpdf \ifx\BKM@temp\BKM@driver \else \PackageWarningNoLine{bookmark}{% Wrong driver `\BKM@driver', using `pdftex' instead% }% \let\BKM@driver\BKM@temp \fi \else \ifx\BKM@temp\BKM@driver \PackageError{bookmark}{% Wrong driver, pdfTeX is not running in PDF mode.\MessageBreak Package loading is aborted% }\@ehc \expandafter\expandafter\expandafter\endinput \fi \def\BKM@temp{dvipdfm}% \ifxetex \ifx\BKM@temp\BKM@driver \else \PackageWarningNoLine{bookmark}{% Wrong driver `\BKM@driver',\MessageBreak using `dvipdfm' for XeTeX instead% }% \let\BKM@driver\BKM@temp \fi \else \def\BKM@temp{vtex}% \ifvtex \ifx\BKM@temp\BKM@driver \else \PackageWarningNoLine{bookmark}{% Wrong driver `\BKM@driver',\MessageBreak using `vtex' for VTeX instead% }% \let\BKM@driver\BKM@temp \fi \else \ifx\BKM@temp\BKM@driver \PackageError{bookmark}{% Wrong driver, VTeX is not running in PDF mode.\MessageBreak Package loading is aborted% }\@ehc \expandafter\expandafter\expandafter\endinput \fi \fi \fi \fi \InputIfFileExists{bkm-\BKM@driver.def}{}{% \PackageError{bookmark}{% Unsupported driver `\BKM@driver'.\MessageBreak Package loading is aborted% }\@ehc \endinput } % \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}{\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}{\ReadBookmarks} % \begin{macrocode} \let\ReadBookmarks\relax % \end{macrocode} % \end{macro} % % \begin{macrocode} % % \end{macrocode} % % \subsection{Driver for dvipdfm} % % \begin{macrocode} %<*dvipdfm> \NeedsTeXFormat{LaTeX2e} \ProvidesFile{bkm-dvipdfm.def}% [2023-12-10 v1.31 bookmark driver for dvipdfm (HO)]% % \end{macrocode} % % \begin{macro}{\BKM@id} % \begin{macrocode} \newcount\BKM@id \BKM@id=\z@ % \end{macrocode} % \end{macro} % % \begin{macro}{\BKM@0} % \begin{macrocode} \@namedef{BKM@0}{000} % \end{macrocode} % \end{macro} % \begin{macro}{\ifBKM@sw} % \begin{macrocode} \newif\ifBKM@sw % \end{macrocode} % \end{macro} % % \begin{macro}{\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<>% }% \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}{\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} % % \end{macrocode} % % \subsection{Driver for \hologo{VTeX}} % % \begin{macrocode} %<*vtex> \NeedsTeXFormat{LaTeX2e} \ProvidesFile{bkm-vtex.def}% [2023-12-10 v1.31 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}{\BKM@id} % \begin{macrocode} \newcount\BKM@id \BKM@id=\z@ % \end{macrocode} % \end{macro} % % \begin{macro}{\BKM@0} % \begin{macrocode} \@namedef{BKM@0}{00} % \end{macrocode} % \end{macro} % \begin{macro}{\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{% % }% \fi \else \edef\BKM@action{}% \fi \else \BKM@EscapeName\BKM@named \edef\BKM@action{% % }% \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{% >% }% \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}{\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}{\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}{\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}{\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}{\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}{\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}{\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}{\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}{\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}{\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}{\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} % % \end{macrocode} % % \subsection{Driver for \hologo{pdfTeX}} % % \begin{macrocode} %<*pdftex> \NeedsTeXFormat{LaTeX2e} \ProvidesFile{bkm-pdftex.def}% [2023-12-10 v1.31 bookmark driver for pdfTeX and luaTeX (HO)]% % \end{macrocode} % % \begin{macro}{\BKM@DO@entry} % \begin{macrocode} \def\BKM@DO@entry#1#2{% \begingroup \kvsetkeys{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{<>}}% \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{<>}% }% \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 \pdfoutline\BKM@attr\BKM@action count\ifBKM@DO@open\else-\fi\BKM@x@childs {\BKM@DO@title}% \endgroup } % \end{macrocode} % \end{macro} % \begin{macro}{\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} % % \end{macrocode} % % \begin{macrocode} %<*pdftex|pdfmark> % \end{macrocode} % \begin{macro}{\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} % % \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}% [2023-12-10 v1.31 bookmark driver for dvips (HO)]% % \end{macrocode} % \begin{macro}{\BKM@PSHeaderFile} % \begin{macrocode} \def\BKM@PSHeaderFile#1{% \special{PSfile=#1}% } % \end{macrocode} % \begin{macro}{\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} % % \end{macrocode} % % \subsubsection{Common part} % % \begin{macrocode} %<*pdfmark> % \end{macrocode} % % \begin{macro}{\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}{\BKM@write} % \begin{macrocode} \def\BKM@write#{% \immediate\write\BKM@file } % \end{macrocode} % \end{macro} % % \begin{macro}{\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 \kvsetkeys{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} % % \end{macrocode} % % \subsection{Common part for \xoption{pdftex} and \xoption{pdfmark}} % % \begin{macrocode} %<*pdftex|pdfmark> % \end{macrocode} % % \subsubsection{Write auxiliary file} % % \begin{macrocode} \AddToHook{begindocument}{% \immediate\write\@mainaux{\string\providecommand\string\BKM@entry[2]{}}} % \end{macrocode} % % \begin{macro}{\BKM@id} % \begin{macrocode} \newcount\BKM@id \BKM@id=\z@ % \end{macrocode} % \end{macro} % % \begin{macro}{\BKM@0} % \begin{macrocode} \@namedef{BKM@0}{000} % \end{macrocode} % \end{macro} % \begin{macro}{\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}{\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}{\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}{\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}{\BKM@LuaTeX@InitFile} % \begin{macrocode} \ifluatex \def\BKM@LuaTeX@InitFile{% \begingroup \toks@={}% \edef\x{\endgroup \def\noexpand\BKM@srcfile{% \the\expandafter\toks@ \directlua{% if status and status.filename then % tex.settoks('toks@', status.filename)% end% }% }% }\x }% \else \let\BKM@LuaTeX@InitFile\relax \fi % \end{macrocode} % \end{macro} % % \subsubsection{Read auxiliary data} % % \begin{macrocode} \SetupKeyvalOptions{family=BKM@DO,prefix=BKM@DO@} \DeclareStringOption[0]{id} \DeclareBoolOption{open} \DeclareStringOption{flags} \DeclareStringOption{color} \DeclareStringOption{dest} \DeclareStringOption{named} \DeclareStringOption{uri} \DeclareStringOption{gotor} \DeclareStringOption{page} \DeclareStringOption{view} \DeclareStringOption{rawaction} \DeclareStringOption{srcline} \DeclareStringOption{srcfile} % \end{macrocode} % % \begin{macrocode} \AtBeginDocument{% \let\BKM@entry\BKM@DO@entry } % \end{macrocode} % % \begin{macrocode} % % \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} % % \end{macrocode} % % \subsubsection{Drivers using hooks at end of document} % % Driver \xoption{pdftex} use the LaTeX hook \xoption{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> \ifBKM@atend \AddToHook{enddocument/afterlastpage}{% \BKM@EndHook }% \fi % % \end{macrocode} % % \subsubsection{Drivers using \xoption{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 \xoption{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} %<*dvipdfm|vtex|pdfmark> \ifBKM@atend \AddToHook{shipout/lastpage}{\BKM@EndHook}% \fi % % \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} % \def\t{^^A % \begin{tabular}{@{}>{\ttfamily}l@{ $\rightarrow$ }>{\ttfamily}l@{}} % bookmark.sty & tex/latex/bookmark/bookmark.sty\\ % bkm-dvipdfm.def & tex/latex/bookmark/bkm-dvipdfm.def\\ % bkm-dvips.def & tex/latex/bookmark/bkm-dvips.def\\ % bkm-pdftex.def & tex/latex/bookmark/bkm-pdftex.def\\ % bkm-vtex.def & tex/latex/bookmark/bkm-vtex.def\\ % bkm-dvipdfm-2019-12-03.def & tex/latex/bookmark/bkm-dvipdfm-2019-12-03.def\\ % bkm-dvips-2019-12-03.def & tex/latex/bookmark/bkm-dvips-2019-12-03.def\\ % bkm-pdftex-2019-12-03.def & tex/latex/bookmark/bkm-pdftex-2019-12-03.def\\ % bkm-vtex-2019-12-03.def & tex/latex/bookmark/bkm-vtex-2019-12-03.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}^^A % }^^A % \sbox0{\t}^^A % \ifdim\wd0>\linewidth % \begingroup % \advance\linewidth by\leftmargin % \advance\linewidth by\rightmargin % \edef\x{\endgroup % \def\noexpand\lw{\the\linewidth}^^A % }\x % \def\lwbox{^^A % \leavevmode % \hbox to \linewidth{^^A % \kern-\leftmargin\relax % \hss % \usebox0 % \hss % \kern-\rightmargin\relax % }^^A % }^^A % \ifdim\wd0>\lw % \sbox0{\small\t}^^A % \ifdim\wd0>\linewidth % \ifdim\wd0>\lw % \sbox0{\footnotesize\t}^^A % \ifdim\wd0>\linewidth % \ifdim\wd0>\lw % \sbox0{\scriptsize\t}^^A % \ifdim\wd0>\linewidth % \ifdim\wd0>\lw % \sbox0{\tiny\t}^^A % \ifdim\wd0>\linewidth % \lwbox % \else % \usebox0 % \fi % \else % \lwbox % \fi % \else % \usebox0 % \fi % \else % \lwbox % \fi % \else % \usebox0 % \fi % \else % \lwbox % \fi % \else % \usebox0 % \fi % \else % \lwbox % \fi % \else % \usebox0 % \fi % \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 % (\TeX\,Live, \mikTeX, \dots) relies on file name databases, you must refresh % these. For example, \TeX\,Live\ users run \verb|texhash| or % \verb|mktexlsr|. % % \paragraph{Generating the documentation.} % You can use the \xfile{.dtx} to generate % the documentation. The process can be configured by the % configuration file \xfile{ltxdoc.cfg}. For instance, put this % line into this file, if you want to have A4 as paper format: % \begin{quote} % \verb|\PassOptionsToClass{a4paper}{article}| % \end{quote} % An example follows how to generate the % documentation with pdf\LaTeX: % \begin{quote} %\begin{verbatim} %pdflatex bookmark.dtx %makeindex -s gind.ist bookmark.idx %pdflatex bookmark.dtx %makeindex -s gind.ist bookmark.idx %pdflatex bookmark.dtx %\end{verbatim} % \end{quote} % % \begin{thebibliography}{9} % % \bibitem{hyperref} % Sebastian Rahtz, Heiko Oberdiek: % \textit{The \xpackage{hyperref} package}; % 2011/04/17 v6.82g; % \CTANpkg{hyperref} % % \bibitem{currfile} % Martin Scharrer: % \textit{The \xpackage{currfile} package}; % 2011/01/09 v0.4. % \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= | can be replaced by % \verb|color=[rgb]{,,}|. % \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} % \end{History} % % \PrintIndex % % \Finale \endinput