diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/xbmks/xbmks.dtx |
Initial commit
Diffstat (limited to 'macros/latex/contrib/xbmks/xbmks.dtx')
-rw-r--r-- | macros/latex/contrib/xbmks/xbmks.dtx | 779 |
1 files changed, 779 insertions, 0 deletions
diff --git a/macros/latex/contrib/xbmks/xbmks.dtx b/macros/latex/contrib/xbmks/xbmks.dtx new file mode 100644 index 0000000000..b2ed3074c1 --- /dev/null +++ b/macros/latex/contrib/xbmks/xbmks.dtx @@ -0,0 +1,779 @@ +%\iffalse +% makeindex -s gglo.ist -o xbmks.gls xbmks.glo +% makeindex -s gind.ist -o xbmks.ind xbmks.idx +%<*copyright> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% xbmks.sty package, %% +%% Copyright (C) 2016--2018 %% +%% dpstory@uakron.edu %% +%% %% +%% This program can redistributed and/or modified under %% +%% the terms of the LaTeX Project Public License %% +%% Distributed from CTAN archives in directory %% +%% macros/latex/base/lppl.txt; either version 1.2 of the %% +%% License, or (at your option) any later version. %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%</copyright> +%<package>\NeedsTeXFormat{LaTeX2e}[1997/12/01] +%<package>\ProvidesPackage{xbmks} +%<package> [2018/07/04 v2.0.2 xbmks: Cross-document bookmarks (dps)] +%<*driver> +\documentclass{ltxdoc} +\usepackage{xcolor} +\usepackage[colorlinks,hyperindex=false,bookmarksopen]{hyperref} +\usepackage{fancyvrb,array,calc} +\usepackage{xbmks} +\xbmksetup{colors={int=red},styles={intbf}} +%\pdfstringdefDisableCommands{\let\\\textbackslash} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\bgroup\ttfamily +\gdef\brpr#1{\char123\relax#1\char125\relax}\egroup +\let\darg\brpr +\let\env\texttt +\let\opt\texttt +\let\pkg\textsf +\let\app\textsf +\def\visispace{\symbol{32}} +%\def\hardspace{{\fontfamily{cmtt}\selectfont\symbol{32}}} +\def\ameta#1{\ensuremath{\langle\textit{\texttt{#1}}\rangle}} +\def\meta#1{\textsl{\texttt{#1}}} +\def\SUB#1{\ensuremath{{}_{\mbox{\scriptsize\ttfamily#1}}}} +\def\cs#1{\texttt{\bslash#1}} +\DeclareRobustCommand{\tmspace}[3]{% + \ifmmode\mskip#1#2\else\kern#1#3\fi\relax} +\renewcommand{\,}{\tmspace+\thinmuskip{.1667em}} +\let\thinspace\, +\renewcommand{\!}{\tmspace-\thinmuskip{.1667em}} +\let\negthinspace\! +\renewcommand{\:}{\tmspace+\medmuskip{.2222em}} +\let\medspace\: +\newcommand{\negmedspace}{\tmspace-\medmuskip{.2222em}} +\renewcommand{\;}{\tmspace+\thickmuskip{.2777em}} +\let\thickspace\; +\newcommand{\negthickspace}{\tmspace-\thickmuskip{.2777em}} +\makeatletter +\renewcommand{\paragraph} + {\@startsection{paragraph}{4}{0pt}{6pt}{-3pt} + {\normalfont\normalsize\bfseries}} +\renewenvironment{quote}[1][] + {\def\@rgi{#1}\ifx\@rgi\@empty + \let\rghtm\@empty\else\def\rghtm{\rightmargin\leftmargin}\fi + \list{}{\rghtm} %{\rightmargin\leftmargin}% + \item\relax} + {\endlist} +\makeatother +\InputIfFileExists{aebdocfmt.def}{\PackageInfo{xbmks}{Inputting aebdocfmt.def}} + {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax + \PackageInfo{xbmks}{aebdocfmt.def cannot be found}} +\begin{document} +\def\CMD#1{\textbackslash#1} + \GetFileInfo{xbmks.sty} + \title{\textsf{xbmks}: Cross-document bookmarks} + \author{D. P. Story\\ + Email: \texttt{dpstory@acrotex.net}} + \date{processed \today} + \maketitle + \tableofcontents + \let\Email\texttt + \DocInput{xbmks.dtx} +\IfFileExists{\jobname.ind}{\newpage\setupFullwidth\par\PrintIndex}{\paragraph*{Index} The index goes here.\\Execute + \texttt{makeindex -s gind.ist -o xbmks.ind xbmks.idx}\\on the command line and recompile + \texttt{xbmks.dtx}.} +\IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of changes goes here.\\Execute + \texttt{makeindex -s gglo.ist -o xbmks.gls xbmks.glo}\\on the command line and recompile + \texttt{xbmks.dtx}.} +\end{document} +%</driver> +% \fi +% \MakeShortVerb{|} +% +% \InputIfFileExists{aebdonotindex.def}{\PackageInfo{web}{Inputting aebdonotindex.def}} +% {\PackageInfo{web}{cannot find aebdonotindex.def}} +% +% \begin{macrocode} +% Begin package +%<*package> +\RequirePackage{xkeyval} +\RequirePackage{ifpdf}[2006/02/20] +\RequirePackage{ifxetex}[2006/08/21] +% \end{macrocode} +% +%\section{Description} +% More than a couple decades ago (counting back from 2018), I wrote two mathematics tutorials: \textsl{\href{http://www.math.uakron.edu/~dpstory/e-calculus.html}{eCalculus}} and +% \textsl{\href{http://www.math.uakron.edu/~dpstory/mpt_home.html}{Algebra Review in Ten Lessons}}. The tutorials consisted of a number of lessons, each in a separate PDF. +% The bookmarks of each lessons contained the table of contents for the whole tutorial. A student, in theory, could then +% jump from one lesson to another by selecting an entry of interest from the bookmarks. In the intervening years I have not seen +% a {\LaTeX} package for merging the table of contents of a set of PDFs and merge them in this each member of the +% set. This package attempts to do just that. +% +% \section{Drivers and options} +% We support the drivers \app{dvips} (and \app{dvipsone}), \app{pdflatex}, \app{lualatex}, and \app{xelatex}; these +% options are then named \opt{dvipsone}, \opt{dvips}, \opt{pdftex}, \opt{luatex}, and \opt{xetex}. +% \changes{v1.1}{2018/06/13}{Fixed misspelling of drive command for pdfmark case} +% \begin{macrocode} +\def\xbmk@driver{xbmks-pdfmark.def} +\DeclareOptionX{dvipsone}{\def\xbmk@driver{xbmks-pdfmark.def}} +\DeclareOptionX{dvips}{\def\xbmk@driver{xbmks-pdfmark.def}} +\DeclareOptionX{pdftex}{\def\xbmk@driver{xbmks-pdftex.def}} +\DeclareOptionX{luatex}{\def\xbmk@driver{xbmks-pdftex.def}} +\DeclareOptionX{xetex}{\def\xbmk@driver{xbmks-xetex.def}} +% \end{macrocode} +% \section{Process the options} +% \begin{macrocode} +\ifpdf\ExecuteOptionsX{pdftex}\else +\ifxetex\ExecuteOptionsX{xetex}\else + \let\ExecuteOptions@SAVE\ExecuteOptions + \let\ExecuteOptions\ExecuteOptionsX + \InputIfFileExists{web.cfg}{} + {\@ifundefined{l@tex@@@@driver}{\ExecuteOptionsX{dvips}} + {\ExecuteOptionsX{dvipsone}}}% + \let\ExecuteOptions\ExecuteOptions@SAVE +\fi\fi +\ProcessOptionsX +% \end{macrocode} +% \section{Requirements} +% The minimal requirement is \pkg{hyperref} and its built-in bookmark system. It is important to note that +% the \pkg{bookmark} package is not supported. +% \begin{macrocode} +\RequirePackage{hyperref} +% \end{macrocode} +% \begin{macro}{\xbmksetup} +% Set the cross-document options: +% \changes{v1.1}{2018/06/13}{Allow an empty value of docbundle, its value is set to \string\cs{jobname}}% +%\begin{quote}\ttfamily\obeylines +%\string\xbmksetup\darg{% +%\qquad docbundle=\darg{\ameta{doc\SUB1},\ameta{doc\SUB2},...,\ameta{doc\SUB{n}}}, +%\qquad colors=\darg{int=\ameta{color},ext=\ameta{color}}, +%\qquad styles=\darg{intbf,extbf,intit,extit} +%} +%\end{quote} +%This command must appear in one and only one of the document bundle, perhaps one +%of the documents you are calling the `main file'. It writes +%the key-values to the file \texttt{xbmks.cfg} which is then read back in by the other +%members of the document bundle, as specified by the \texttt{dobundle} key. The base names +%of the document bundle must match the name given to it by \cs{jobname}, exact spelling, case +%sensitive. +% +%\paragraph*{Key-values for \cs{xbmksetup}.} The keys belonging to the \texttt{xbmksetup} family: +%\IndexOpt{docbundle}\texttt{docbundle}, \IndexOpt{colors}\texttt{colors}, and \IndexOpt{styles}\texttt{styles}. +% \begin{macrocode} +\define@key{xbmksetup}{docbundle}[]{\def\x@bmks@docs{#1}} +\let\x@bmks@docs\@empty +\define@key{xbmksetup}{colors}[]{\def\x@bmks@colors{#1}} +\let\x@bmks@colors\@empty +\define@key{xbmksetup}{styles}[]{\def\x@bmks@styles{#1}} +\let\x@bmks@styles\@empty +% \end{macrocode} +%\subparagraph*{Values for the key \texttt{colors}.} The value recognized are +%\begin{quote}\ttfamily +% colors=\darg{int=\ameta{color},ext=\ameta{color}} +%\end{quote} +%If the value of \texttt{int} or \texttt{ext} is empty, then the PDF viewer's default +%colors are using (black). +% \begin{macrocode} +\define@key{xbmk@colors}{int}[]{% + \HyColor@BookmarkColor{#1}{\xbmks@intC}{xbmks}{int}% + \ifx\xbmks@intC\@empty\else + \edef\xbmks@intC{/C[\xbmks@intC]}\fi +} +\let\xbmks@intC\@empty +\define@key{xbmk@colors}{ext}[]{% + \HyColor@BookmarkColor{#1}{\xbmks@extC}{xbmks}{ext}% + \ifx\xbmks@extC\@empty\else + \edef\xbmks@extC{/C[\xbmks@extC]}\fi +} +\let\xbmks@extC\@empty +\let\xbmks@Yes=y \let\xbmks@No=n +% \end{macrocode} +%\subparagraph*{Values for the key \texttt{colors}.} The value recognized are +%\begin{quote}\ttfamily +% styles=\darg{intbf,intit,extbf,extit} +%\end{quote} +%These are valueless keys (Boolean keys, actually). \texttt{intbf} means the interior document bookmarks +%are set in bold while \texttt{intbf,intit} creates bold and italic font. +% \begin{macrocode} +\define@boolkey{xbmk@styles}{intbf}[true]{} +\define@boolkey{xbmk@styles}{extbf}[true]{} +\define@boolkey{xbmk@styles}{intit}[true]{} +\define@boolkey{xbmk@styles}{extit}[true]{} +% \end{macrocode} +% We evaluate the values of \cs{xbmksetup} by getting the values of +% the \texttt{xbmksetup} family. +% \begin{macrocode} +\newcommand{\xbmksetup}[1]{\setkeys{xbmksetup}{docbundle,#1}% +% \end{macrocode} +% \changes{v2.0.2}{2018/07/04}{Added an empty docbundle argument. This solves a problem +% that the bookmarks not appearing after an even number of compiles.} +% \begin{macrocode} + \ifx\x@bmks@docs\@empty +% \end{macrocode} +% If there is no \texttt{docbundle} is specified, we use \cs{jobname} as its +% value. +% \begin{macrocode} + \PackageInfo{xbmks}{The docbundle key of \string\xbmksetup\space + is empty,\MessageBreak + I will give it a value of `\jobname',\MessageBreak + in hopes this is your intention}% + \gdef\xbmk@cnt{1}% + \def\xbmks@next{\write@xbmks@cfg{docbundle={\jobname},#1}}\else + \def\xbmks@next{\write@xbmks@cfg{#1}}\fi\xbmks@next +} +% \end{macrocode} +% We write the key-values of \cs{xbmksetup} to the hard drive in the file +% \texttt{xbmks.cfg}, this is \cs{xbmksetupi\darg{\ameta{KVPairs}}}. \cs{xbmksetupi} +% is defined below, it is the command that actually does the heavy lifting in +% processing the key-values. +% \begin{macrocode} +\def\write@xbmks@cfg#1{% + \newwrite\xbmks@setup \immediate\openout \xbmks@setup xbmks.cfg + \set@display@protect + \immediate\write\xbmks@setup{\protect\xbmksetupi{#1}}% + \set@typeset@protect + \immediate\closeout\xbmks@setup +} +% \end{macrocode} +% \cs{xbmksetupi} is an internal command that sets the key-values across all files in the \texttt{docbundle}. +% \begin{macrocode} +\newcommand{\xbmksetupi}[1]{% + \setkeys{xbmksetup}{#1}% + \edef\x{\noexpand\x@docbundle{\x@bmks@docs}}\x + \edef\x{\noexpand + \setkeys{xbmk@colors}{\x@bmks@colors}}\x + \edef\x{\noexpand + \setkeys{xbmk@styles}{\x@bmks@styles}}\x + \let\xbmk@intF\@empty + \ifKV@xbmk@styles@intit + \ifKV@xbmk@styles@intbf + \def\xbmk@intF{/F 3}\else + \def\xbmk@intF{/F 1}\fi + \else + \ifKV@xbmk@styles@intbf + \def\xbmk@intF{/F 2}\fi + \fi + \let\xbmk@extF\@empty + \ifKV@xbmk@styles@extit + \ifKV@xbmk@styles@extbf + \def\xbmk@extF{/F 3}\else + \def\xbmk@extF{/F 1}\fi + \else + \ifKV@xbmk@styles@extbf + \def\xbmk@extF{/F 2}\fi + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\x@docbundle} +% is a comma-delimited list of document base names: +%\begin{quote}\ttfamily\obeylines +%\string\x@docbundle\darg{\ameta{doc\SUB1},\ameta{doc\SUB2},...,\ameta{doc\SUB{n}}} +%\end{quote} +%This command is called internally by \cs{xbmksetupi}. +% \begin{macrocode} +\def\xbmkcsarg#1#2{\expandafter#1\csname#2\endcsname} +\xdef\xbmk@cnt{0} +\newcommand{\x@docbundle}[1]{\bgroup + \def\thisDoc{\jobname}\count\z@=0 % + \edef\@tmpexp{\noexpand\@for\noexpand\@arg:=#1}% + \@tmpexp\do{\advance\count\z@ by 1\relax + \edef\x{\noexpand\xbmk@recordDoc{\@arg}}\x + \edef\x{\noexpand\xbmk@docID{\@arg}}\x + }% + \xdef\xbmk@cnt{\the\count\z@}\egroup +} +\newcommand{\xbmk@recordDoc}[1]{% + \xbmkcsarg\xdef{xbmk@doc\the\count\z@}{#1}} +% \end{macrocode} +% Because we are bringing in multiple outline files, there may be duplicate anchor names. +% We assign each file in the document bundle a unique ID `\texttt{x1\ameta{anchor}}', `\texttt{x2\ameta{anchor}}', etc. +% The IDs are ultimately assigned through \cs{pdfbookmarkx}. +% \begin{macrocode} +\newcommand{\xbmk@docID}[1]{% + \xbmkcsarg\xdef{x#1}{x\the\count\z@}} +\xbmkcsarg\xdef{x\jobname}{x0} +% \end{macrocode} +% \end{macro} +% +% \section{Extending bookmarks to arbitrary actions} +% +% It is possible to create bookmarks with arbitrary actions, just as the \pkg{bookmark} +% package, does. Here we try to use \pkg{hyperref}'s native bookmark support. The +% \pkg{hyperref} commands \cs{pdfbookmark}, \cs{currentbookmark}, \cs{subpdfbookmark}, and +% \cs{belowpdfbookmark} are modified. +% \begin{macro}{\pdfbookmarkx}\hskip-\marginparsep\, +% \texttt{[\ameta{level}]\darg{\ameta{text}}[\ameta{xbmkskeys-kvp}]\darg{\ameta{name}}}\\ +% Defines a bookmark at \ameta{level}. If \ameta{level} is not provided, the level 1 is assumed. +% We write to the outline file the action desired for this bookmark. +% \cs{currentAction} is defined below. We do not set an anchor; if the +% document author wants an anchor, he should use \cs{pdfbookmark}. As with +% \cs{pdfbookmark}, the \cs{pdfbookmarkx} should not normally be directly +% used. +% \paragraph*{Key-values for the `\cs{...bookmarkx}' commands.} Recognized keys are +% \IndexKey{action}\texttt{action}, \IndexKey{color}\texttt{color}, and \IndexKey{style}\texttt{style}. +% Note that these keys are singular, as opposed to \texttt{colors} and \texttt{styles} defined in the +% \texttt{xbmksetup} family. This is the \texttt{xbmkskeys} family. +% \changes{v2.0}{2018/06/21}{Added `\string\cs{...bookmarkx} commands} +% \changes{v2.0.1}{2018/06/25}{Added key-values for action, color, and style for custom `\string\cs{...bookmarkx} commands} +% \begin{macrocode} +\define@key{xbmkskeys}{action}{\def\x@bmks@action{#1}} +\let\x@bmks@action\@empty +\define@key{xbmkskeys}{color}[]{% + \HyColor@BookmarkColor{#1}{\x@bmks@C}{xbmks}{color}% + \ifx\x@bmks@C\@empty\else + \edef\x@bmks@C{/C[\x@bmks@C]}\fi +} +\let\x@bmks@C\@empty +\define@key{xbmkskeys}{style}[]{% + \edef\x{\noexpand\setkeys{xbmks@style}{#1}}\x + \let\x@bmks@F\@empty + \ifKV@xbmks@style@it + \ifKV@xbmks@style@bf + \def\x@bmks@F{/F 3}\else + \def\x@bmks@F{/F 1}\fi + \else + \ifKV@xbmks@style@bf + \def\x@bmks@F{/F 2}\fi + \fi +} +\let\x@bmks@F\@empty +% \end{macrocode} +% The \texttt{style} key takes zero, one, or two values, these are \texttt{bf} and \texttt{it}. +% \begin{macrocode} +\define@boolkey{xbmks@style}{bf}[true]{} +\define@boolkey{xbmks@style}{it}[true]{} +\def\x@rollCFIntoActionBmrk#1{% + \xbmkcsarg\ifx{X_#1}\relax + \let\x@bmks@C\@empty\let\x@bmks@F\@empty\fi + \ifx\xbmk@J\xbmk@filename + \ifx\x@bmks@C\@empty\let\thisCol\xbmks@intC\else + \let\thisCol\x@bmks@C\fi + \ifx\x@bmks@F\@empty\let\thisF\xbmk@intF\else + \let\thisF\x@bmks@F\fi + \else + \ifx\x@bmks@C\@empty\let\thisCol\xbmks@extC\else + \let\thisCol\x@bmks@C\fi + \ifx\x@bmks@F\@empty\let\thisF\xbmk@extF\else + \let\thisF\x@bmks@F\fi + \fi + \global\let\x@bmks@C\@empty\global\let\x@bmks@F\@empty +} +% \end{macrocode} +% We finally arrive at \cs{pdfbookmarkx} command. +% \begin{macrocode} +\newcommand\pdfbookmarkx[2][0]{% + \@ifnextchar[%] + {\pdfbookmarkx@i{#1}{#2}} + {\pdfbookmarkx@i{#1}{#2}[]}} +\def\pdfbookmarkx@i#1#2[#3]#4{% level, title, action, name + \def\x@rgiii{#3}\ifx\x@rgiii\@empty +% \end{macrocode} +% if there is no action, treat as a destination +% \begin{macrocode} + \Hy@writebookmark{}{#2}{#4.#1}{#1}{toc}% + \hyper@anchorstart{#4.#1}\hyper@anchorend + \else + \protected@write\@outlinefile{}{% + \string\nextAction% assign doc ID + {\@nameuse{x\jobname}#4.#1}{#3}}% + \Hy@writebookmark{}{#2}{\@nameuse{x\jobname}#4.#1}{#1}{toc}% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\currentpdfbookmarkx} +% \hskip-\marginparsep\,\texttt{\darg{\ameta{text}}[\ameta{xbmkskeys-kvp}]\darg{\ameta{name}}}\\ +% The \texttt{action=\ameta{action}} is raw PDF code, for example, +%\begin{quote}\ttfamily +%\string\currentpdfbookmarkx[/S/URI/URI(http://www.acrotex.net)]\\\null +%\qquad\darg{http://www.acrotex.net}\darg{home} +%\end{quote} +% The command creates a bookmark at the current +% bookmark level in the outline tree and associates the specified \ameta{action}. The argument +% \ameta{text} appears in the bookmark panel. The \ameta{name} is used for identification purposes. +% \begin{macrocode} +\newcommand{\currentpdfbookmarkx}[1]{% + \@ifnextchar[%] + {\currentpdfbookmarkx@i{#1}} + {\currentpdfbookmarkx@i{#1}[]}} +\def\currentpdfbookmarkx@i#1[#2]#3{% + \pdfbookmarkx[\Hy@currentbookmarklevel]{#1}[{#2}]{#3}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\subpdfbookmarkx} +% \hskip-\marginparsep\,\texttt{\darg{\ameta{text}}[\ameta{\ameta{xbmkskeys-kvp}}]\darg{\ameta{name}}}\\ +% Reduces the current bookmark level by one, then creates +% the bookmark at that level. The reduced level is the new current +% bookmark level. +% \begin{macrocode} +\newcommand{\subpdfbookmarkx}[1]{% + \@ifnextchar[%] + {\subpdfbookmarkx@i{#1}} + {\subpdfbookmarkx@i{#1}[]}} +\def\subpdfbookmarkx@i#1[#2]#3{% + \@tempcnta\Hy@currentbookmarklevel + \Hy@StepCount\@tempcnta + \expandafter + \pdfbookmarkx\expandafter[\the\@tempcnta]{#1}[{#2}]{#3}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\belowpdfbookmarkx} +% \hskip-\marginparsep\,\texttt{\darg{\ameta{text}}[\ameta{xbmkskeys-kvp}]\darg{\ameta{name}}}\\ +% Creates a bookmark at one level below the current +% bookmark level without changing the value of the current bookmark +% level. +% \begin{macrocode} +\newcommand{\belowpdfbookmarkx}[1]{% + \@ifnextchar[%] + {\belowpdfbookmarkx@i{#1}} + {\belowpdfbookmarkx@i{#1}[]}} +\def\belowpdfbookmarkx@i#1[#2]#3{% + \@tempcnta\Hy@currentbookmarklevel + \Hy@StepCount\@tempcnta + \expandafter + \pdfbookmarkx\expandafter[\the\@tempcnta]{#1}[{#2}]{#3}% + \advance\@tempcnta by -1 % + \xdef\Hy@currentbookmarklevel{\the\@tempcnta}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\nextAction@i} +% \hskip-\marginparsep\,\texttt{\darg{\ameta{anchor.level}}\darg{\ameta{xbmkskeys-kvp}}}\\ +% This command is used internally, the document author need not do anything. +% The command \cs{nextAction} is \cs{let} to \cs{nextAction@i} just prior to when +% the outline file is input; and is \cs{let} to \cs{@gobbletwo}, otherwise. +% \begin{macrocode} +\def\nextAction@i#1#2{\@ifundefined{X_#1}{% + \setkeys{xbmkskeys}{#2}% + \xbmkcsarg\xdef{X_#1}{\x@bmks@action}% + }{\global\xbmkcsarg\let{X_#1}\relax + \PackageWarning{xbmks} + {The anchor name `#1' is already defined,\MessageBreak + change this name, the bookmark will be created\MessageBreak + but it will have no associated action}}} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +\def\x@outWarningMsg{\PackageWarningNoLine{xbmks}{% +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\MessageBreak +@@ Outline files were not input, compile again @@\MessageBreak +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}}% +% \end{macrocode} +% These commands are implemented in the driver dependent sections. +% \begin{macrocode} +% End package +%</package> +%<*pdfmark> +% \end{macrocode} +% \section{Driver dependent code} +% \subsection{The pdfmark driver} +% We redefine/modify the \cs{ReadBookmarks} command of \pkg{hyperref}, +% this definition is driver dependent. +% \begin{macrocode} +\def\ReadBookmarks{% + \pdf@ifdraftmode{}{% + \begingroup\def\\{\@backslashchar\@backslashchar}% dps + \def\calc@bm@number##1{% + \@tempcnta=\check@bm@number{##1}\relax + \advance\@tempcnta by 1 % + \expandafter\edef\csname B_##1\endcsname{\the\@tempcnta}% + }% + \def\do##1{% + \ifnum\catcode`##1=\active + \@makeother##1% + \else + \ifnum\catcode`##1=6 % + \@makeother##1% + \fi + \fi + }% + \dospecials + \Hy@safe@activestrue + \escapechar=`\\% + \ifx\WriteBookmarks\relax + \global\let\WriteBookmarks\relax + \fi + \begingroup + \def\WriteBookmarks{0}% + \count\z@=0\relax + \edef\xbmk@J{\jobname}% + \@whilenum \count\z@<\xbmk@cnt\relax\do{% + \advance\count\z@ by 1 % + \edef\xbmk@thisdoc{xbmk@doc\the\count\z@}% + \edef\xbmk@filename{\@nameuse{\xbmk@thisdoc}}% + \@onelevel@sanitize\xbmk@filename + \bgroup + \def\@@BOOKMARK[##1][##2]##3##4##5{% + \calc@bm@number{##5}% + }% + \let\nextAction\@gobbletwo + \InputIfFileExists{\xbmk@filename.out}{}{\x@outWarningMsg}% + \def\@@BOOKMARK[##1][##2]##3##4##5{% + \def\Hy@temp{##4}% +% \end{macrocode} +% If `\texttt{X\_\#\#3}' is undefined (\cs{relax}), it is a normal bookmark. +% \begin{macrocode} + \xbmkcsarg\ifx{X_##3}\relax + \ifx\xbmk@J\xbmk@filename + \pdfmark{% + pdfmark=/OUT,% + Count={##2\check@bm@number{##3}},% + Raw={\xbmks@intC\xbmk@intF},% + Dest={##3},% + Title=\expandafter\strip@prefix\meaning\Hy@temp + }% + \else + \pdfmark{% + pdfmark=/OUT,% + Count={##2\check@bm@number{##3}},% + Raw={\xbmks@extC\xbmk@extF},% + Action=/GoToR,% + File={\xbmk@filename.pdf},% + Dest={##3},% + Title=\expandafter\strip@prefix\meaning\Hy@temp + }% + \fi + \else +% \end{macrocode} +% The anchor has an `\texttt{X\_}' definition, it is a bookmark created +% from one of the `\texttt{bookmarkx}' commands. We treat this as a separate case. +% \begin{macrocode} + \x@rollCFIntoActionBmrk{##3}% + \pdfmark{% + pdfmark=/OUT,% + Count={##2\check@bm@number{##3}},% + Raw={/Action<<\@nameuse{X_##3}>>\thisCol\thisF},% + Title=\expandafter\strip@prefix\meaning\Hy@temp + }% + \fi + }% bookmark + \let\nextAction\nextAction@i + \InputIfFileExists{\xbmk@filename.out}{}{}% + \egroup + }% \@whilenum + \endgroup + \endgroup + }% + \ifx\WriteBookmarks\relax\else + \if@filesw + \newwrite\@outlinefile + \Hy@OutlineRerunCheck + \immediate\openout\@outlinefile=\jobname.out\relax + \ifHy@typexml + \immediate\write\@outlinefile{<relaxxml>\relax}% + \fi + \fi + \fi +} +%</pdfmark> +% \end{macrocode} +% \subsection{Code for pdftex/luatex driver} +% We redefine/modify the \cs{ReadBookmarks} command of \pkg{hyperref}, +% this definition is driver dependent. +% \begin{macrocode} +%<*pdftex> +\def\ReadBookmarks{% + \pdf@ifdraftmode{}{% + \begingroup\def\\{\@backslashchar\@backslashchar}% dps + \def\calc@bm@number##1{% + \@tempcnta=\check@bm@number{##1}\relax + \advance\@tempcnta by 1 % + \expandafter\edef\csname B_##1\endcsname{\the\@tempcnta}% + }% + \def\Hy@OutlineName##1##2##3##4{\def\@rgi{##1}% + \expandafter\pdfoutline\ifx\@rgi\@empty\else + attr {##1} \fi + user {##2} count##3{##4}% + % goto name{#2} count#3{#4}% + }% + \def\do##1{% + \ifnum\catcode`##1=\active + \@makeother##1% + \else + \ifnum\catcode`##1=6 % + \@makeother##1% + \fi + \fi + }% + \dospecials + \Hy@safe@activestrue + \escapechar=`\\% + \ifx\WriteBookmarks\relax + \global\let\WriteBookmarks\relax + \fi + \begingroup + \def\WriteBookmarks{0}% + \count\z@=0\relax + \edef\xbmk@J{\jobname}% + \@whilenum \count\z@<\xbmk@cnt\relax\do{% + \advance\count\z@ by 1 % + \edef\xbmk@thisdoc{xbmk@doc\the\count\z@}% + \edef\xbmk@filename{\@nameuse{\xbmk@thisdoc}}% + \@onelevel@sanitize\xbmk@filename + \bgroup + \gdef\@@BOOKMARK[##1][##2]##3##4##5{% + \calc@bm@number{##5}% + }% + \let\nextAction\@gobbletwo + \InputIfFileExists{\xbmk@filename.out}{}{\x@outWarningMsg}% + \gdef\@@BOOKMARK[##1][##2]##3##4##5{% + \def\Hy@temp{##4}% + \Hy@pstringdef\Hy@pstringName{\HyperDestNameFilter{##3}}% + \xbmkcsarg\ifx{X_##3}\relax +% \end{macrocode} +% Ordinary bookmark +% \begin{macrocode} + \ifx\xbmk@J\xbmk@filename + \Hy@OutlineName{\xbmks@intC\xbmk@intF}{<</S/GoTo% + /D(\Hy@pstringName)>>}{% + ##2\check@bm@number{\Hy@pstringName}% + }{% + \expandafter\strip@prefix\meaning\Hy@temp + }% + \else + \Hy@OutlineName{\xbmks@extC\xbmk@extF}{<</S/GoToR% + /F(\xbmk@filename.pdf)/D(\Hy@pstringName)>>}{% + ##2\check@bm@number{##3}% + }{% + \expandafter\strip@prefix\meaning\Hy@temp + }% + \fi + \else +% \end{macrocode} +% Bookmark created by one of the `\texttt{...bookmarkx} commands +% \begin{macrocode} + \x@rollCFIntoActionBmrk{##3}% + \Hy@OutlineName{\thisCol\thisF} + {<<\@nameuse{X_##3}>>}{% + ##2\check@bm@number{\Hy@pstringName}% + }{% + \expandafter\strip@prefix\meaning\Hy@temp + }% + \fi + }% bookmark + \let\nextAction\nextAction@i + \InputIfFileExists{\xbmk@filename.out}{}{}% + \egroup + } % \@whilenum + \endgroup + }% + \ifx\WriteBookmarks\relax + \else + \if@filesw + \newwrite\@outlinefile + \Hy@OutlineRerunCheck + \immediate\openout\@outlinefile=\jobname.out\relax + \ifHy@typexml + \immediate\write\@outlinefile{<relaxxml>\relax}% + \fi + \fi + \fi +} +%</pdftex> +%<*xetex> +% \end{macrocode} +% \subsection{Code for xetex driver} +% We redefine/modify the \cs{ReadBookmarks} command of \pkg{hyperref}, +% this definition is driver dependent. +% \begin{macrocode} +\def\ReadBookmarks{% + \pdf@ifdraftmode{}{% + \begingroup\def\\{\@backslashchar\@backslashchar}% dps + \def\calc@bm@number##1{% + \@tempcnta=\check@bm@number{##1}\relax + \advance\@tempcnta by 1 % + \expandafter\edef\csname B_##1\endcsname{\the\@tempcnta}% + }% + \def\do##1{% + \ifnum\catcode`##1=\active + \@makeother##1% + \else + \ifnum\catcode`##1=6 % + \@makeother##1% + \fi + \fi + }% + \dospecials + \Hy@safe@activestrue + \escapechar=`\\% + \ifx\WriteBookmarks\relax + \global\let\WriteBookmarks\relax + \fi + \begingroup + \def\WriteBookmarks{0}% + \count\z@=0\relax + \edef\xbmk@J{\jobname}% + \@whilenum \count\z@<\xbmk@cnt\relax\do{% + \advance\count\z@ by 1 % + \edef\xbmk@thisdoc{xbmk@doc\the\count\z@}% + \edef\xbmk@filename{\@nameuse{\xbmk@thisdoc}}% + \@onelevel@sanitize\xbmk@filename + \bgroup + \def\@@BOOKMARK[##1][##2]##3##4##5{% + \calc@bm@number{##5}% + }% + \let\nextAction\@gobbletwo + \InputIfFileExists{\xbmk@filename.out}{}{\x@outWarningMsg}% + \def\@@BOOKMARK[##1][##2]##3##4##5{% + \def\Hy@temp{##4}% + \Hy@pstringdef\Hy@pstringName{\HyperDestNameFilter{##3}}% + \x@rollCFIntoActionBmrk{##3}% + \@pdfm@mark{% + outline \ifHy@DvipdfmxOutlineOpen + [\ifnum##21>\z@\else-\fi] \fi + ##1<<% + /Title(\expandafter\strip@prefix\meaning\Hy@temp)% + \xbmkcsarg\ifx{X_##3}\relax +% \end{macrocode} +% Ordinary bookmark +% \begin{macrocode} + \ifx\xbmk@J\xbmk@filename + /A<<% + /S/GoTo% + /D(\Hy@pstringName)% + >>% + \else + /A<<% + /S/GoToR/F(\xbmk@filename.pdf)% + /D(\Hy@pstringName)% + >>% + \fi + \else +% \end{macrocode} +% Bookmark created by one of the \texttt{\string\...bookmarkx} commands +% \begin{macrocode} + /A<<\@nameuse{X_##3}>> + \fi + \thisCol\thisF + >>% + }% \@pdfm@mark + \let\thisC\@empty\let\thisF\@empty + }% bookmark + \let\nextAction\nextAction@i + \InputIfFileExists{\xbmk@filename.out}{}{}% + \egroup + }% \@whilenum + \endgroup + \endgroup + }% + \ifx\WriteBookmarks\relax + \else + \if@filesw + \newwrite\@outlinefile + \Hy@OutlineRerunCheck + \immediate\openout\@outlinefile=\jobname.out\relax + \ifHy@typexml + \immediate\write\@outlinefile{<relaxxml>\relax}% + \fi + \fi + \fi +} +%</xetex> +%<*package> +\InputIfFileExists{xbmks.cfg}{}{} +\@ifpackageloaded{bookmark}{\PackageWarningNoLine{xbmks}{The + bookmark package is not supported;\MessageBreak + this package does nothing, as a result}} +{\InputIfFileExists{\xbmk@driver}{}{}} +%</package> +% \end{macrocode} +% \Finale |