% This is the Navigator package. % Relevant information can be found in navigator-doc.pdf % % Author: Paul Isambert. % E-mail: zappathustra AT free DOT fr % Comments and suggestions are welcome. % Date: January 2011. \ifdefined\NavigatorHasAlreadyBeenLoadedMyDear \expandafter\endinput \fi \let\NavigatorHasAlreadyBeenLoadedMyDear\relax \input yax \ifdim\yaxversion pt<1.03pt \senderror{Navigator}{YaX should be at least version 1.03. I quit}% \expandafter\endinput \fi \ifnum\texenginenumber>1 \lettocs\ifpdforluatex{iftrue} \else \letcstocs{ifpdforluatex}{iffalse} \fi \newsyntax#1:#2;{nav@} \setcatcodes{_@=11} \def\nav@error#1{\senderror{Navigator}{#1}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%% Strings %%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ifcase\texenginenumber \or % XeTeX: we do nothing. Under some circumstances, % xdvipdfmx writes a good UTF-16 string. \let\pdfstring\unbrace \or % PDFTeX: we escape the string. \let\pdfstring\pdfescapestring \or % LuaTeX: the string is converted from UTF-8 to % UTF-16, and expressed in octal form (otherwise LuaTeX % would complain about non-UTF-8 characters). Hexadecimal % strings may be better, but \pdfoutline encloses the title % between braces, whereas hexadecimal strings should be % enclosed between "<" and ">". % % The UTF-16 conversion covers the entire Unicode range, % because one has the right to use Linear-B or musical notations % in a bookmark, but the viewer is very unlikely to display % anything beside the basic plane (unless one can change % the UI's font). % One could use a catcode table for this, but I don't think % it's worth it. {\catcode`\_=0 \catcode`\\=12 _gdef_navbackslash{\}} \bgroup \catcode`\%=12 \directlua{ local function to8 (...) local arg, str = {...}, "" for _, num in ipairs(arg) do str = str .. string.format("\noexpand\\navbackslash%.3o", num) end return str end function toutf16(str) local result = "" for c in string.utfvalues(str) do if c < 0x10000 then result = result .. to8(c / 256, c % 256) else c = c - 0x10000 local a, b = c / 1024 + 0xD800, c % 1024 + 0xDC00 result = result .. to8(a / 256, a % 256, b / 256, b % 256) end end tex.print([[\noexpand\navbackslash376\noexpand\navbackslash377]] .. result) end } \egroup \long\def\pdfstring#1{% \directlua{toutf16("\luaescapestring{#1}")}% } \fi %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%% Object creation %%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \def\pdfobjectstatus#1{% \ifcs{nav@pdfobject:#1} {\ifcs{nav@pdfobject_used:#1}{2}{1}} {0}% } \def\ifpdfobject#1{% \ifcs{nav@pdfobject:#1}% } \def\pdfobject#1#2{% \nav@pdfobject{}{}[]{#1}{#2}% } \def\pdfdictobject#1#2{% \nav@pdfobject{}{}[]{#1}{<< #2 >>}% } \def\pdfstreamobject{% \ifnext[ {\nav@pdfobject{stream}{}} {\nav@pdfobject{stream}{}[]}% } \def\pdffileobject{% \ifnext[ {\nav@pdfobject{stream}{file}} {\nav@pdfobject{stream}{file}[]}% } \ifpdforluatex \def\nav@pdfobject#1#2[#3]#4#5{% \ifnum\pdfobjectstatus{#4}=2 \nav@error{There already exists an object named `#4'}% \else \immediate\pdfobj \ifnum\pdfobjectstatus{#4}=1 useobjnum \pdfobjectnumber{#4}\fi #1 % "stream" or nothing. \reverse\iffemptystring{#3}{attr {#3} }% "attr {...}" or nothing. #2 % "file" or nothing. {#5}% Contents. \ifnum\pdfobjectstatus{#2}=0 \xdefcs{nav@pdfobject:#4}{\the\pdflastobj}% \fi \global\letcs{nav@pdfobject_used:#4}\relax \fi } \def\pdfreserveobject#1{% \ifcase\pdfobjectstatus{#1} \pdfobj reserveobjnum \xdefcs{nav@pdfobject:#1}{\the\pdflastobj}% \or \nav@error{Object `#1' is already reserved}% \or \nav@error{Object `#1' is already in use}% \fi } % An error message here wouldn't reach the terminal % but would spoil the PDF file instead; therefore % I prefer to return an unexisting (and impossible) % object with number 0. \def\pdfobjectnumber#1{% \ifcs{nav@pdfobject:#1} {\usecs{nav@pdfobject:#1}} {0}% } \def\pdfrefobject#1{% \ifcs{nav@pdfobject:#1} {\usecs{nav@pdfobject:#1} 0 R} {0 0 R}% } \else \def\nav@pdfobject#1#2[#3]#4#5{% \ifnum\pdfobjectstatus{#4}=2 \nav@error{There already exists an object named `#4'}% \else \special{pdf: \ifemptystring{#1} % No matter whether the object has been reserved, % it doesn't mean anything with xdvipdfmx. {obj \pdfrefobject{#4} #5} {\ifemptystring{#2}{stream}{fstream} \pdfrefobject{#4} (#5) \reverse\iffemptystring{#3}{<< #3 >>}}}% % Useless. But so the same behavior can be expected % no matter the driver. \global\defcs{nav@pdfobject:#4}{@nav_#4}% \global\letcs{nav@pdfobject_used:#4}\relax \fi } \def\pdfreserveobject#1{% \ifcase\pdfobjectstatus{#1} % We do absolutely nothing except register the object % as ``reserved''. \xdefcs{nav@pdfobject:#1}{@nav_#1}% \or % Stupid, but then the same behavior can be expected % across engines. \nav@error{Object `#1' is already reserved}% \or \nav@error{Object `#1' is already in use}% \fi } % We can't do anything meaningful here, so we do nothing. \def\pdfobjectnumber#1{} % With XeTeX, referencing of unreserved % object is allowed, because reserving objects is % dummy behavior anyway. Thus, rather than returning % an unexisting 0 object, at least there exists the % possibility that the object will be created later, % even if it hasn't been reserved yet. \def\pdfrefobject#1{@nav_#1} \fi \def\pdfensureobject#1{% \ifpdfobject{#1}{}{\pdfreserveobject{#1}}% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%% Anchors %%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % REMARK % % Here and elsewhere, \usevalueor (or similar) is used (with a default % value as the or-part), because the user might do something like: % % \setparameter param: % up = 12pt % % \anchor[meta = param]{foo} % % Then there is no value for the "left" attribute, since "param" % doesn't have "navigator" (which holds the user's default values) % as a meta-parameter. % If no meta is detected, "navigator" is assigned to meta. \def\nav@prepare_options#1#2{% \setparameterlist{nav@temp}[#1]{#2}% \nav@ifattribute nav@temp:meta; {}{\nav@setattribute nav@temp:meta; = navigator }% } \def\anchor{% \ifnext[ {\nav@anchor} {\nav@anchor[]}% } \def\nav@anchor[#1]#2{% \ifcs{nav@pdfanchor:#2} {\nav@error{Anchor `#2' already exists}} {\global\letcs{nav@pdfanchor:#2}\relax \nav@prepare_options{\gobbleone}{#1}% \nav@anchor_position{#2}% \deleteparameter nav@temp:}% } \def\nav@anchor_position#1{% \ifvmode \nav@passvalueand{\nav@anchor_pass{nav@pdfanchor:#1}}nav@temp:fit;{{\nav@usevalue nav@temp:zoom;}} {\nav@anchor_pass{nav@pdfanchor:#1}{xyz}{}}% \else \vbox to 0pt{\vss \vbox to \nav@usevalueor nav@temp:up;{\baselineskip}{% \hbox to 0pt{% \kern-\nav@usevalueor nav@temp:left;{0pt}% \nav@passvalueand{\nav@anchor_pass{nav@pdfanchor:#1}}nav@temp:fit;{{\nav@usevalue nav@temp:zoom;}} {\nav@anchor_pass{nav@pdfanchor:#1}{xyz}{}}\hss}\vss}}% \fi } \def\nav@anchor_pass#1#2#3{% \lowercase{\nav@anchor_create{#2}}{#1}{#3}% } \ifpdforluatex \def\nav@anchor_xyz #1{xyz zoom 0#1} \def\nav@anchor_fit #1{fit} \def\nav@anchor_fith #1{fith} \def\nav@anchor_fitv #1{fitv} \def\nav@anchor_fitb #1{fitb} \def\nav@anchor_fitbh #1{fitbh} \def\nav@anchor_fitbv #1{fitbv} \def\nav@anchor_fitr #1{fitr} \def\nav@anchor_create#1#2#3{% \pdfdest name {#2} \ifcs{nav@anchor_#1}{\usecs{nav@anchor_#1}{#3}}{xyz}% } \else % FitR is quite unusable with xdvipdfm. {\setcatcodes{pt=12}\gdef\noPT#1pt{#1}} \def\nav@anchor_xyz #1{XYZ @xpos @ypos \expandafter\noPT\the\dimexpr0#1pt/1000\relax} \def\nav@anchor_fit #1{Fit} \def\nav@anchor_fith #1{FitH @ypos} \def\nav@anchor_fitv #1{FitV @xpos} \def\nav@anchor_fitb #1{FitB} \def\nav@anchor_fitbh #1{FitBH @ypos} \def\nav@anchor_fitbv #1{FitBV @xpos} \def\nav@anchor_create#1#2#3{% \special{pdf: dest (#2) [ @thispage /\ifcs{nav@anchor_#1}{\usecs{nav@anchor_#1}{#3}}{XYZ} ] }% } \fi \def\anchorname#1{% nav@pdfanchor:#1% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%% Outlines %%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \def\nav@pdfdef_list{} \def\pdfdef#1{% \global\addright\nav@pdfdef_list{#1}% \gdefcs{nav@pdfdef:\commandtoname#1}% } \newfor\nav@pdfdef_loop#1{% \lettocs#1{nav@pdfdef:\commandtoname#1}% } \def\outline{% \ifnext[ {\nav@outline} {\nav@outline[]}% } \def\nav@outline[#1]#2{% \ifnext[ {\nav@outline_do{#1}{#2}} {\nav@outline_do{#1}{#2}[]}% } \newcount\nav@outline_count \ifpdforluatex \def\nav@outline_do#1#2[#3]#4{% \global\advance\nav@outline_count 1 \gdefcs{nav@outline_\the\nav@outline_count:specs}{#1,}% \gdefcs{nav@outline_\the\nav@outline_count:level}{#2}% \gdefcs{nav@outline_\the\nav@outline_count:title}{#4}% \nav@prepare_options{\gobbleone}{#1}% \nav@outline_getaction{#1}{#3}% % It'd be simpler to create one action object anyway and let \nav@outline_n:action % refer to it; but then I'd have to use the /NoAction trick (in \nav@outline_getaction), which not all % viewers understand; at least here outlines with destinations work. \global\xdefcs{nav@outline_\the\nav@outline_count:action}{<< \nav@temp >>}% \deleteparameter nav@temp:% } \def\nav@processoutlines{% \bgroup \passexpanded\nav@pdfdef_loop\nav@pdfdef_list \nav@processoutlines_loop{1}% \egroup } \newwhile\nav@processoutlines_loop1{#1+1} {\straightenif{ifnum}{\numexpr#1>\nav@outline_count} {\breakwhile{}} {\nav@processoutlines_subloop{#1+1}{#1}{}{0}}% } \newwhile\nav@processoutlines_subloop4{#1+1}{#2}{#3}{#4} {\straightenif{ifnum}{\numexpr#1>\nav@outline_count} {\breakwhile{\nav@processoutlines_create{#2}{#4}}} {\straightenif{ifdim}{\usecs{nav@outline_\the\numexpr#2:level}pt<\usecs{nav@outline_\the\numexpr#1:level}pt\relax} {\ifemptystring{#3} {\changewhile{#1+1}{#2}{#1}{#4+1}} {\reverse\straighteniff{ifdim}{\usecs{nav@outline_\the\numexpr#3:level}pt<\usecs{nav@outline_\the\numexpr#1:level}pt\relax} {\changewhile{#1+1}{#2}{#1}{#4+1}}}} {\breakwhile{\nav@processoutlines_create{#2}{#4}}}}% } \def\nav@processoutlines_create#1#2{% \passexpandedcs{\nav@prepare_options{}}{nav@outline_\the\numexpr#1:specs}% \pdfoutline attr {\nav@outline_attributes} user {\usecs{nav@outline_\the\numexpr#1:action}} count \nav@ifvalue nav@temp:open; = true {}{-}\numexpr#2\relax {\pdfstring{\usecs{nav@outline_\the\numexpr#1:title}}}% \deleteparameter nav@temp:% } \else % % So much simpler because xdvipdfmx deals with children % automatically; thus \nav@processoutlines is unnecessary. % \let\nav@processoutlines\relax \def\nav@outline_do#1#2[#3]#4{% \global\advance\nav@outline_count 1 \nav@prepare_options{\gobbleone}{#1}% \nav@outline_getaction{#1}{#3}% \bgroup \passexpanded\nav@pdfdef_loop\nav@pdfdef_list % \special{pdf: out [\nav@ifvalue nav@temp:open;=true {}{-}] #2 << /Title (#4) /A << \nav@temp >> \nav@outline_attributes >>}% % \egroup \deleteparameter nav@temp:% } \fi \def\nav@outline_getaction#1#2{% \nav@storevalueand\nav@temp nav@temp:anchor; {\edef\nav@temp{/S/GoTo /D (\anchorname{\nav@temp})}} {\nav@storevalueand\nav@temp nav@temp:action; {\pdfensureobject{\nav@temp}% \edef\nav@temp{/S/Named /N/NoAction /Next \pdfrefobject{\nav@temp}}} {\nav@anchor[#1]{\ifemptystring{#2}{outline_\the\nav@outline_count}{#2}}% \edef\nav@temp{/S/GoTo /D (\anchorname{\ifemptystring{#2}{outline_\the\nav@outline_count}{#2})}}}}% } \def\nav@outline_attributes{% % See REMARK above for default values. /C [\nav@usevalueor nav@temp:color;{\nav@usevalueor nav@temp:outlinecolor;{0 0 0}}] /F \nav@ifvalue nav@temp:bold; = true {1}{0}\nav@ifvalue nav@temp:italic; = true {1}{0} } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%% Annotations %%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \def\actionlink{% \ifnext[ {\nav@actionlink_do{a}} {\nav@actionlink_do{a}[]}% } \def\rawactionlink{% \ifnext[ {\nav@actionlink_do{r}} {\nav@actionlink_do{r}[]}% } \def\jumplink{% \ifnext[ {\nav@actionlink_do{d}} {\nav@actionlink_do{d}[]}% } \def\annotation{% \ifnext[ {\nav@actionlink_do{x}} {\nav@actionlink_do{x}[]}% } \def\openfilelink{% \ifnext[ {\nav@openfilelink} {\nav@openfilelink[]}% } \def\nav@openfilelink[#1]#2{% \ifnext[ {\nav@openfilelink_do{#1}{#2}} {\nav@openfilelink_do{#1}{#2}[0]}% } \def\nav@openfilelink_do#1#2[#3]{% \nav@actionlink_do{r}[#1] {/S/GoToE /D [\the\numexpr#3-1\relax /Fit] /T << /R/C /N (#2) >> /NewWindow true}% } \long\def\nav@actionlink_do#1[#2]#3#4{% \nav@quitvmode \nav@prepare_options{}{#2}% \iffstring{#1}{a}{\pdfensureobject{#3}}% \nav@actionlink_create{#1}{#3}{% % Something in pre might be delimited by something in post % so post must be passed expanded. \nav@passvaluenobracesor{\nav@usevalue nav@temp:pre;#4}nav@temp:post; {\nav@usevalue nav@temp:pre;#4}% }% \deleteparameter nav@temp:% } \ifpdforluatex \let\nav@quitvmode\quitvmode \long\def\nav@actionlink_create#1#2#3{% \pdfstartlink attr {\nav@actionlink_attributes{#1}{#2}} user {}% #3\pdfendlink } \else \let\nav@quitvmode\leavevmode \long\def\nav@actionlink_create#1#2#3{% \special{pdf: bannot << \nav@actionlink_attributes{#1}{#2} >>}% #3\special{pdf: eannot}% } \fi \def\nav@actionlink_attributes#1#2{% /Border [0 0 \nav@usevalueor nav@temp:border;{1}% \nav@passvaluenobracesand{[}nav@temp:dash;{]}{}] /C [\nav@usevalueor nav@temp:color;{\nav@usevalueor nav@temp:linkcolor;{0 0 0}}] \nav@ifcasevalue nav@temp:highlight;% \val none /H/N \val invert /H/I \val outline /H/O \val push /H/P \endval \ifstring{#1}{x} {#2} {/Subtype/Link \ifstring{#1}{d} {/Dest (\anchorname{#2})} {/A \ifstring{#1}{r} {<< #2 >>} {\pdfrefobject{#2}}}}% \nav@usevalue nav@temp:raw;% } \pdfdictobject{firstpage}{/S/Named /N/FirstPage} \pdfdictobject{lastpage} {/S/Named /N/LastPage} \pdfdictobject{prevpage} {/S/Named /N/PrevPage} \pdfdictobject{nextpage} {/S/Named /N/NextPage} \def\urlaction#1#2{% \pdfdictobject{#1}{/S/URI /URI (#2)}% } \def\javascriptaction#1#2{% \pdfdictobject{#1}{/S/JavaScript /JS (\pdfstring{#2})}% } \def\urllink{% \ifnext[ {\nav@urllink} {\nav@urllink[]}% } \def\nav@urllink[#1]#2{% \nav@actionlink_do{r}[#1]{/S/URI /URI (#2)}% } \def\javascriptlink{% \ifnext[ {\nav@javascriptlink} {\nav@javascriptlink[]}% } \def\nav@javascriptlink[#1]#2{% \nav@actionlink_do{r}[#1]{/S/JavaScript /JS (\pdfstring{#2})}% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%% Embedded files %%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \def\nav@embeddedfile_names{}% \ifcase\texenginenumber \or % XeTeX \def\nav@sort#1#2{% \straightenif{ifnum}{\strcmp{#1}{#2} < 0\relax}% } \or % PDFTeX \def\nav@sort#1#2{% \straightenif{ifnum}{\pdfstrcmp{#1}{#2} < 0\relax}% } \or % LuaTeX \def\nav@sort#1#2{% \usecs{% \directlua{% if [[#1]] < [[#2]] then tex.print("firstoftwo") else tex.print("secondoftwo") end}}} \fi \def\embeddedfile{% \ifnext[ {\nav@embeddedfile_getdesc} {\nav@embeddedfile_getdesc[]}% } \def\nav@embeddedfile_getdesc[#1]#2{% \ifnext[ {\nav@embeddedfile_do{#1}{#2}} {\nav@embeddedfile_do{#1}{#2}[]}% } \def\nav@embeddedfile_do#1#2[#3]#4{%s \pdffileobject[/Type/EmbeddedFile]{nav@embeddedfile:#2}{#4}% \pdfdictobject{#2}{% /Type/Filespec /F (\ifemptystring{#3}{#4}{#3}) \reverse\iffemptystring{#1}{/Desc (\pdfstring{#1})} /EF << /F \pdfrefobject{nav@embeddedfile:#2} >>}% \let\nav@temp\nav@embeddedfile_names \let\nav@embeddedfile_names\emptycs \passexpanded{\ifemptystring{#3}{\nav@embeddedfile_add{#4}}{\nav@embeddedfile_add{#3}}{\pdfrefobject{#2}}}\nav@temp } \newfor\nav@embeddedfile_add{2}#3#4{% \nav@sort{#1}{#3} {\global\eaddright\nav@embeddedfile_names{{#1}{#2}{#3}{#4}}% \retrieverest{\global\eaddright\nav@embeddedfile_names}} {\global\eaddright\nav@embeddedfile_names{{#3}{#4}}}% }[\global\eaddright\nav@embeddedfile_names{{#1}{#2}}] \newfor\nav@embeddedfile_print#1#2{(#1) #2} \def\nav@embeddedfile_process{% \pdfdictobject{EmbeddedFiles}{/Names [\passexpanded\nav@embeddedfile_print\nav@embeddedfile_names]}% \nav@embeddedfile_setnames } \ifpdforluatex \def\nav@embeddedfile_setnames{% \pdfnames{/EmbeddedFiles \pdfrefobject{EmbeddedFiles}}% } \else \def\nav@embeddedfile_setnames{% \special{pdf: put @names << /EmbeddedFiles \pdfrefobject{EmbeddedFiles} >>}% } \fi %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%% INFO %%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newif\ifnav@finished \def\finishpdffile{% \unless\ifnav@finished \global\nav@finishedtrue \nav@embeddedfile_process \nav@processoutlines \nav@processinfo \fi } \setparameter navigator : % ANCHORS (and bookmarks which create implicit anchors) up = \baselineskip left = 0pt fit = xyz % zoom = 1000 % If it is set, it always sets view to 100%, which is extremely irritating. % % LINKS border = 0 linkcolor = "0 0 0" % "color" in individual links highlight = invert % dash = 1 0 % raw = makes sense for individual links only % pre = nothing % post = nothing % % OUTLINES outlinecolor = "0 0 0" % "color" in individual outlines open = false bold = false italic = false % action = makes sense for individual outlines only % anchor = idem % % PDF info, no default values: % author, title, keywords, subject, date, moddate, % creator, producer, rawinfo % % PDF catalog, idem: % layout, mode, uri or base, openaction, rawcatalog \def\nav@processinfo_do#1#2{% \nav@passvalueand{/#1 (\pdfstring}navigator:#2;{) }{}% } \def\nav@processinfo{% \nav@info{% \nav@processinfo_do{Author} {author}% \nav@processinfo_do{Title} {title}% \nav@processinfo_do{Keywords} {keywords}% \nav@processinfo_do{Subject} {subject}% \nav@processinfo_do{CreationDate} {date}% \nav@processinfo_do{ModDate} {moddate}% \nav@processinfo_do{Creator} {creator}% \nav@processinfo_do{Producer} {producer}% \nav@usevalue navigator:rawinfo;}% % \nav@passvalue\pdfensureobject navigator:openaction;% \nav@catalog{% \nav@ifattribute navigator:layout; {/PageLayout% \nav@ifcasevalue navigator:layout;% \val onepage /SinglePage \val onecolumn /OneColumn \val twopage /TwoPageRight \val twopage* /TwoPageLeft \val twocolumn /TwoColumnRight \val twocolumn* /TwoColumnLeft \endval\spacecs}{}% \nav@ifattribute navigator:mode; {/PageMode \nav@ifcasevalue navigator:mode;% \val outlines /UseOutlines \val bookmarks /UseOutlines \val thumbnails /UseThumbs \val thumbs /UseThumbs \val oc /UseOC \val attachments /UseAttachments \val files /UseAttachments \elseval /UseOutlines \endval\spacecs}{}% \nav@ifattribute navigator:uri; {/URI << /Base (\nav@usevalue navigator:uri;) >> } {\nav@ifattribute navigator:base; {/URI << /Base (\nav@usevalue navigator:base;) >> } {}}% \nav@passvalue{/OpenAction \pdfrefobject}navigator:openaction;% \nav@usevalue navigator:rawcatalog;}% }% \ifpdforluatex \let\nav@info\pdfinfo \let\nav@catalog\pdfcatalog \else \def\nav@info#1{% \special{pdf: docinfo << #1 >>}% } \def\nav@catalog#1{% \special{pdf: docview << #1 >>}% } \fi \restorecatcodes \endinput % Almost 800 lines? Gee, that code was supposed to % be short and light...