% % Need some discussion on workflow % % makeindex < aebpro_man.idx > aebpro_man.ind \documentclass[10pt]{article} \usepackage[fleqn]{amsmath} \usepackage[ web={centertitlepage,designv,forcolorpaper,latextoc,pro,addtoHyOpts={pagebackref=false}}, eforms, % linktoattachments, aebxmp ]{aeb_pro} \usepackage{aeb_mlink} \usepackage{xbmks} \usepackage{graphicx,array} %\usepackage{myriadpro} %\usepackage{calibri} \usepackage[altbullet]{lucidbry} \DeclareInitView{layoutmag={navitab:UseOutlines}} \xbmksetup{colors={int=red},styles={intbf}} \addtolength{\marginparwidth}{20pt} %\previewtrue %\usepackage{makeidx} %\makeindex \usepackage{acroman} \usepackage[active]{srcltx} \setcounter{secnumdepth}{4} \setcounter{tocdepth}{5} \makeatletter \renewcommand*{\theparagraph}{\texorpdfstring{\protect\P\protect\ }{\textparagraph}} \renewcommand{\paragraph} {\renewcommand{\@seccntformat}[1]{\theparagraph}% \@startsection{paragraph}{4}{0pt}{6pt}{-3pt}{\color{\aeb@subsubsectioncolor}\bfseries}} \renewcommand*\l@paragraph{\@dottedtocline{4}{5.0em}{1em}} %{7.0em}{4.1em}} \def\chgCurrLblName#1{\def\@currentlabelname{#1}} \def\echgCurrLblName#1{\edef\@currentlabelname{#1}} \makeatother %\getDimsFromGraphic{graphics/dpsweb}{\dpswebW}{\dpswebH} %\urlstyle{rm} \urlstyle{sf} \let\uif\textsf \let\app\textsf \def\psf#1{\textbf{\textsf{#1}}} %\let\amtIndent\leftmargini \edef\amtIndent{\the\parindent} \renewcommand*\descriptionlabel[1]{\hspace\labelsep \normalfont #1} \DeclareDocInfo { university={Acro\negthinspace\TeX.Net}, title={The \textsf{xbmks} package\texorpdfstring{\\}{: }Cross-document bookmarks}, author={D. P. Story}, email={dpstory@acrotex.net}, subject={Documentation for the xbmks package from AcroTeX: cross-document bookmarks}, talksite={\url{www.acrotex.net}}, version={v2.0.2, 2018/07/04}, Keywords={AcroTeX, bookmarks, cross-document, document bundle}, copyrightStatus=True, copyrightNotice={Copyright (C) \the\year, D. P. Story}, copyrightInfoURL={http://www.acrotex.net} } \def\dps{$\hbox{$\mathfrak D$\kern-.3em\hbox{$\mathfrak P$}% \kern-.6em \hbox{$\mathcal S$}}$} \universityLayout{fontsize=Large} \titleLayout{fontsize=LARGE} \authorLayout{fontsize=Large} \tocLayout{fontsize=Large,color=aeb} \sectionLayout{indent=-62.5pt,fontsize=large,color=aeb} \subsectionLayout{indent=-31.25pt,color=aeb} \subsubsectionLayout{indent=0pt,color=aeb} \subsubDefaultDing{\texorpdfstring{$\bullet$}{\textrm\textbullet}} \widestNumber{0.00.} %\pagestyle{empty} %\parindent0pt\parskip\medskipamount \def\dps{$\mbox{$\mathfrak D$\kern-.3em\mbox{$\mathfrak P$}% \kern-.6em \hbox{$\mathcal S$}}$} \newcount\fldCnt \fldCnt=0 \def\incFldCnt{\global\advance\fldCnt1\relax} \frenchspacing \chngDocObjectTo{\newDO}{doc} \begin{docassembly} var titleOfManual="The xbmks package MANUAL"; var manualfilename="Manual_BG_Print_xbmks.pdf"; var manualtemplate="Manual_BG_Brown.pdf"; // Blue, Green, Brown var _pathToBlank="C:/Users/Public/Documents/ManualBGs/"+manualtemplate; var doc; var buildIt=false; if ( buildIt ) { console.println("Creating new " + manualfilename + " file."); doc = \appopenDoc({cPath: _pathToBlank, bHidden: true}); var _path=this.path; var pos=_path.lastIndexOf("/"); _path=_path.substring(0,pos)+"/"+manualfilename; \docSaveAs\newDO ({ cPath: _path }); doc.closeDoc(); doc = \appopenDoc({cPath: manualfilename, oDoc:this, bHidden: true}); f=doc.getField("ManualTitle"); f.value=titleOfManual; doc.flattenPages(); \docSaveAs\newDO({ cPath: manualfilename }); doc.closeDoc(); } else { console.println("Using the current "+manualfilename+" file."); } var _path=this.path; var pos=_path.lastIndexOf("/"); _path=_path.substring(0,pos)+"/"+manualfilename; \addWatermarkFromFile({ bOnTop:false, bOnPrint:false, cDIPath:_path }); \executeSave(); \end{docassembly} \begin{document} \maketitle \pdfbookmarkx[1]{Title Page}[action={\Named{FirstPage}}]{TitlePage} \pdfbookmarkx[1]{Links to AcroTeX.Net}[action={/S/GoTo/D(undefined)},% color=magenta,style={bf}]{acrotex} \belowpdfbookmarkx{http://www.acrotex.net}[action={\URI{http://www.acrotex.net}},% color=magenta,style={bf}]{home} \belowpdfbookmarkx{http://blog.acrotex.net}[action={\URI{http://blog.acrotex.net}},% color=magenta,style={bf}]{blog} \selectColors{linkColor=black} \tableofcontents \selectColors{linkColor=webgreen} \def\AcroT{Acro\!\TeX}\def\cAcroT{\textcolor{blue}{\AcroT}} \def\AcroEB{\AcroT{} eDucation Bundle}\def\cAcroEB{\textcolor{blue}{\AcroEB}} \def\AcroB{\AcroT{} Bundle}\def\cAcroB{\textcolor{blue}{\AcroB}} \def\bUrl{http://www.math.uakron.edu/~dpstory} \hypersetup{linktocpage} \section{Introduction} It has been 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{\mlhref{http://www.math.uakron.edu/~dpstory/mpt_home.html}{Algebra Review in Ten Lessons}}. The tutorials consisted of a number of lessons, each lesson was in a separate PDF. The bookmarks of each lesson contained the table of contents \emph{for the whole tutorial}. A student, in theory, could then jump from one lesson to another by selecting a topic 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. The \pkg{xbmks} package attempts to reproduce this feature. \section{Required packages and options} The only requirement is the \pkg{hyperref} package; there is a negative requirement, the \pkg{bookmark} package is not supported. If it is detected within a \pkg{xbmks} document, normal non-cross-document bookmarks are produced. The only options are driver options, these are \opt{dvips} (\app{Acrobat Distiller} or \app{ps2pdf} can be used as the PDF creator), \opt{pdftex} (and \opt{luatex}, which is treated the same as \opt{pdftex}), and \opt{xetex}. Of course, this is a {\LaTeX} package, so the `la' versions of these applications need to be used. The package auto-detects \app{pdftex} and \app{xetex}, and \opt{dvips} is the default, so there is actually no need to pass the driver option. \section{The preamble command \texorpdfstring{\protect\cs{xbmksetup}}{\textbackslash{xbmksetup}}}\label{s:xbmksetup} The only user command is \cs{xbmksetup}: \bVerb\def\1{\qquad}\takeMeasure{\1docbundle=\darg{\ameta{doc\SUB1},\ameta{doc\SUB2},...,\ameta{doc\SUB{n}}},}% \begin{dCmd}[commandchars=!()]{\bxSize} \xbmksetup{% !1docbundle={!ameta(doc!SUB1),!ameta(doc!SUB2),...,!ameta(doc!SUB(n))}, !1colors={int=!ameta(color),ext=!ameta(color)}, !1styles={intbf,extbf,intit,extit} } \end{dCmd} \eVerb You have a collection of files (as specified by the \texttt{docbundle} key) that you want to merge the bookmarks together so they appear in all the files. However, the \cs{xbmksetup} only appears \textbf{in one and only one of the documents}, perhaps the one that you think of as the main file.\footnote{The main file is the first one listed in the value of the \texttt{docbundle} key.} The argument of \cs{xbmksetup} are written to the file \texttt{xbmks.cfg} and input back into each of the files as they are compiled. This is needed so that across all files in the document bundle, they all obey the very same options. \paragraph*{Description of the key-values} \begin{description} \item[\texttt{docbundle}] (Optional) The value of this key, if present, is a comma-delimited list of base names that are a part of this document collection, or bundle. For example, \begin{Verbatim}[xleftmargin=\amtIndent] docbundle={lesson1,lesson2,lesson3,lesson4} \end{Verbatim} The order the bookmarks are listed in each file of the document bundle is the same order the files are listed in \texttt{docbundle}; in this above example, the bookmarks for \texttt{lesson1} are listed first, than those of \texttt{lesson2}, and so on. The first document listed (\texttt{lesson1}) is where the \cs{xbmksetup} commend is placed. This file might be thought of as the `main' file. \textbf{\textcolor{red}{Important:}} It is extremely important to list the base names the using the same spelling and case as the \cs{jobname} command returns in each of the bundle collection. When each file is compiled, \pkg{xbmks} tries to determine which in the list of \texttt{docbundle} files is the one currently being compiled; it is necessary in order to create a internal jump or an external jump. If anything goes wrong, be sure to check the spelling of each file listed. \textbf{Empty or missing \texttt{docbundle} key.} If this key is missing, then it is assigned a value of \cs{jobname}. As a result, normal bookmarks are generated for the document \cs{jobname}; however, as an extra benefit, the other keys are obeyed (\texttt{colors} and \texttt{styles}). See the sample file \texttt{stand-alone.tex} found in the \texttt{examples} file. This manual uses the \pkg{xbmks} package with, \begin{Verbatim}[xleftmargin=\amtIndent] \xbmksetup{colors={int=red},styles={intbf}} \end{Verbatim} \item[\texttt{colors}] (Optional) For any given document in the bundle, there are two types of links in the bookmarks, a link to an item in the current (or internal) document, or a link to an external document (within the bundle of documents). \begin{itemize} \item \texttt{int=\ameta{color}}, where \ameta{color} is an rgb color. This specifies the color of the link for an internal jump within the current document. Specify the color using the syntax \texttt{\darg{[rgb]{\ameta{r},\ameta{g},\ameta{b}}}}; for example, \begin{Verbatim}[xleftmargin=\amtIndent] colors={int={[rgb]{0,.6,0}} \end{Verbatim} or, if the \pkg{xcolor} package is loaded, \emph{named colors} may be used. \item\texttt{ext=\ameta{color}}, where \ameta{color} is an rgb color. This specifies the color of the link for an external jump to another member of the document bundle. Color specification is the same as for \texttt{int}: \begin{Verbatim}[xleftmargin=\amtIndent] colors={int=red,ext=blue} \end{Verbatim} In the above example, we assume \pkg{xcolor} is loaded and specify the colors accordingly. \textbf{The default color.} If you declare \texttt{int} (or \texttt{ext}) without a value, you get the default, which is the color key is not specified within the PDF document. The \texttt{color} key is optional, in which case, you get the default color. What is the default color? Well, its either white or black, depending on the \textsf{Display Theme}. The PDF viewer (\app{Acrobat} and \app{Acrobat Reader DC} automatically switch colors when the theme is changed). When you specify a color, be aware that what looks good in the \emph{light theme} may not be so visible in a \emph{dark theme}. \end{itemize} \item[\texttt{styles}] (Optional) The Adobe PDF viewer applications also support a bold and italics style. These can be specified for the internal and external documents. \begin{itemize} \item Internal styles (valueless) keys are \texttt{intbf} and \texttt{intit}; zero, one, or two of these may be specified, \begin{Verbatim}[xleftmargin=\amtIndent,commandchars=!()] styles={intbf} % !normalfont(bold font) styles={intit} % !normalfont(italics font) styles={intbf,intit} % !normalfont(bold and italics font) \end{Verbatim} \item External styles (valueless) keys are \texttt{extbf} and \texttt{extit}; zero, one, or two of these may be specified, \begin{Verbatim}[xleftmargin=\amtIndent,commandchars=!()] styles={extbf} % !normalfont(bold font) styles={extit} % !normalfont(italics font) styles={extbf,extit} % !normalfont(bold and italics font) \end{Verbatim} \end{itemize} Of course, all these keys are specified or not, in the \texttt{styles} key: \begin{Verbatim}[xleftmargin=\amtIndent] styles={intbf,extit} \end{Verbatim} Here, we specify bold font for the current document and an italics for an internal document. \end{description} \newtopic\noindent\textbf{Point of personal preference.} After experimenting with various combinations of colors and styles with combinations of themes (light and dark) I prefer no color specified with bold font for the current document and plain font for any external document. I think it's important to make it clear in the bookmark panel which are internal and which are external. The bold font tells the same story independent of theme. Thus,\def\1{\qquad}% \begin{Verbatim}[xleftmargin=\amtIndent,commandchars=!()] \xbmksetup{% !1docbundle={!ameta(doc!SUB1),!ameta(doc!SUB2),...,!ameta(doc!SUB(n))}, !1styles={intbf} } \end{Verbatim} seems to be a reasonable choice of key-values. \section{Creating bookmarks with other actions} The \pkg{hyperref} package provides commands (\cs{pdfbookmark}, \cs{currentpdfbookmark}, \cs{subpdfbookmark}, and \cs{belowpdfbookmark}) designed to create bookmarks that jump to a specified destination in the current document. The \pkg{xbmks} package now defines similar commands in which arbitrary actions may be defined. \bVerb\def\1{\qquad}\takeMeasure{\string\pdfbookmarkx[\ameta{level}]\darg{\ameta{text}}[\ameta{KV-pairs}]\darg{\ameta{name}}}% \begin{dCmd}[commandchars=!()]{\bxSize} \pdfbookmarkx[!ameta(level)]{!ameta(text)}[!ameta(KV-pairs)]{!ameta(name)} \currentpdfbookmarkx{!ameta(text)}[!ameta(KV-pairs)]{!ameta(name)} \subpdfbookmarkx{!ameta(text)}[!ameta(KV-pairs)]{!ameta(name)} \belowpdfbookmarkx{!ameta(text)}[!ameta(KV-pairs)]{!ameta(name)} \end{dCmd} \bVerb If the optional \ameta{KV-pairs} argument is not present, the command behaves just like its \pkg{hyperref} counterpart; \ameta{name} is used to create a destination (or anchor) for the ordinary bookmark link. If \ameta{KV-pairs} is specified, no anchor is created, but \ameta{name} is used to associate the \ameta{action} with the bookmark. \paragraph*{Description of the commands}\leavevmode \begin{aebDescript} \item[\cs{pdfbookmarkx}] Creates a bookmark at level \ameta{level} in the outline tree hierarchy. \item[\cs{currentpdfbookmarkx}] The command creates a bookmark at the current bookmark level in the outline tree. \item[\cs{subpdfbookmarkx}] Reduces the current bookmark level by one, then creates the bookmark at that level. The reduced level is the new current bookmark level. \item[\cs{belowpdfbookmarkx}] Creates a bookmark at one level below the current bookmark level without changing the value of the current bookmark level. \end{aebDescript} \paragraph*{Description of the \ameta{KV-pairs} argument.} The \ameta{KV-pairs} argument accepts up to three key-value pairs: \begin{Verbatim}[xleftmargin=\amtIndent,commandchars=!()] action=!ameta(PDF-action),color=!ameta(color),style=!ameta(!upshape(bf|it)) \end{Verbatim} Notice that \texttt{color} and \texttt{style} are in the singular, as opposed to the plural as they were in description of the key-value pairs for \cs{xbmksetup}, back on page~\pageref{s:xbmksetup}. \begin{aebDescript} \item[\texttt{action=\ameta{PDF-action}}] \ameta{PDF-action} is raw PDF action code. I decided to just keep it simple. Consult Section 8.5 titled `Actions', in particular, read Section~8.5.3 on `Action Types' of the \textsl{PDF Reference Sixth Edition, Version 1.7}.\footnote {\url{https://www.adobe.com/devnet/pdf/pdf_reference_archive.html}} A general syntax for the \ameta{action} is, \begin{Verbatim}[xleftmargin=\amtIndent,commandchars=!()] /S!ameta(action-type)!ameta(other-key-values) \end{Verbatim} Common action-types are \texttt{/URI}, \texttt{/JavaScript}, \texttt{/Named}, and \texttt{/GoToR}. Below are some examples, the ones that appear in the demo files. \begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small] \belowpdfbookmarkx{http://www.acrotex.net} [action={/S/URI/URI(http://www.acrotex.net)}]{home} \currentpdfbookmarkx{Current: Hello world!} [action={/S/JavaScript/JS(app.alert("Hello World!");)}]{bmk1} \subpdfbookmarkx{Sub: First Page}[/S/Named/N/FirstPage]{bmk2} \belowpdfbookmarkx{Go to doc1, page 1} [action={/S/GoToR/F(doc1.pdf)/D[1 /Fit]}]{gotor} \end{Verbatim} \textbf{When \pkg{eforms} is loaded.} The \pkg{eforms} package defines some helper commands for common action types, these are \cs{URI}, \cs{JS}, \cs{Named}, and \cs{GoToR}. The above examples are then written as, \begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small] \belowpdfbookmarkx{http://www.acrotex.net} [action={\URI{http://www.acrotex.net}}]{home} \currentpdfbookmarkx{Current: Hello world!} [action={\JS{app.alert("Hello World!");}}]{bmk1} \subpdfbookmarkx{Sub: First Page} [action={\Named{FirstPage}{]{bmk2} \belowpdfbookmarkx{Go to doc1, page 1} [action={\GoToR/F(doc1.pdf)/D[1 /Fit]}]{gotor} \end{Verbatim} \item[\texttt{color=\ameta{color}}] The value of this key determines the color of the link. The value of \ameta{color} was described in the \texttt{colors} key. If this key is not specified, the value \texttt{int} or \texttt{ext} of the \texttt{colors} key is used, as appropriate. When the value of the \texttt{color} key is specified, the link receives the \ameta{color} across all documents in the bundle. \item[\texttt{style=\ameta{\upshape{bf|it}}}] The value of this key determines the style (\texttt{bf} -- bold, \texttt{it} -- italics); the keys may be used together \texttt{style=\darg{bf,it}} gives bold italics font. When \texttt{style} is not specified, the value of the \texttt{styles} key is used. When \texttt{style} is specified, the same style is assigned across all documents in the bundle. \begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small] \belowpdfbookmarkx{http://www.acrotex.net} [action={\URI{http://www.acrotex.net}}, color=magenta,style=bf]{home} \end{Verbatim} This bookmark is colored magenta in bold across all documents in the bundle. \begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small] \belowpdfbookmarkx{http://www.acrotex.net} [action={\URI{http://www.acrotex.net}}]{home} \end{Verbatim} This bookmark takes on the colors and styles declared by the \texttt{colors} and \texttt{styles} keys. \end{aebDescript} \section{Workflow} Given that you have a collection of files that are to contain a common set of bookmarks, how exactly do you do this? Basically, you treat them the same way as you would when you use the \pkg{xy-hyper} package, used for creating cross document links. \paragraph*{Steps to build the document bundle}\leavevmode \begin{enumerate} \item Compile each document at least twice without deleting any auxiliary files, more if you are using \pkg{xr-hyper}; in particular, without deleting any \textsf{OUT} outline files created by \pkg{hyperref}. In terms of order of compilation, compile the main file first (the one that contains the \cs{xbmksetup} command); this will write the \texttt{xbmks.cfg} file and it will be available to the other files in the bundle as you compile them. \item All files have been compiled twice, now compile them one more time so they can input the updated \textsf{OUT} files of the collection and the \texttt{xbmks.cfg} configuration file that contains your setup options for the whole collection. \item If you are using \app{pdflatex}, \app{lualatex}, or \app{xelatex}, you are done; otherwise, convert each DVI file to PS using \app{dvips}. Finally, convert each PS file in the collection to PDF using \app{Acrobat Distiller} or \app{ps2pdf}. \item Delete all auxiliary file, including \texttt{xbmks.cfg} if you wish. \end{enumerate} If you are on \app{Windows OS}, you can use the \app{\href{http://www.acrotex.net/builders/}{AeB Builder}} utility to build the entire bundle of documents.\footnote{\url{http://www.acrotex.net/builders/}} In that utility, you would select the \app{External cross-references} option, found on the user-interface. \paragraph*{Sample files.} The demonstration files are found in the \texttt{examples} folder. The \pkg{xcolor} package is used, otherwise, the packages used are minimal. \newtopic\noindent Now, back to my retirement. \dps \end{document}