diff options
author | Norbert Preining <norbert@preining.info> | 2021-09-19 03:01:05 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2021-09-19 03:01:05 +0000 |
commit | 996c9b239bde82dc3ef3e5b69cd525e87fdb61a8 (patch) | |
tree | 96b4096d6a17e62dfe310df8a5d4f8bd8a9d7321 /macros/luatex/optex | |
parent | fb07ccd098248248795fb851a3a6479ecafaaa47 (diff) |
CTAN sync 202109190301
Diffstat (limited to 'macros/luatex/optex')
-rw-r--r-- | macros/luatex/optex/pdfextra/README.md | 12 | ||||
-rw-r--r-- | macros/luatex/optex/pdfextra/examples/pdfextra-example-latex.tex | 223 | ||||
-rw-r--r-- | macros/luatex/optex/pdfextra/examples/pdfextra-example.pdf | bin | 385845 -> 385350 bytes | |||
-rw-r--r-- | macros/luatex/optex/pdfextra/examples/pdfextra-example.tex | 76 | ||||
-rw-r--r-- | macros/luatex/optex/pdfextra/pdfextra-doc.pdf | bin | 230095 -> 245952 bytes | |||
-rw-r--r-- | macros/luatex/optex/pdfextra/pdfextra-doc.tex | 122 | ||||
-rw-r--r-- | macros/luatex/optex/pdfextra/pdfextra.opm | 144 | ||||
-rw-r--r-- | macros/luatex/optex/pdfextra/pdfextra.sty | 4 | ||||
-rw-r--r-- | macros/luatex/optex/pdfextra/pdfextra.tex | 364 |
9 files changed, 830 insertions, 115 deletions
diff --git a/macros/luatex/optex/pdfextra/README.md b/macros/luatex/optex/pdfextra/README.md index c47262b1f5..70ef8febf7 100644 --- a/macros/luatex/optex/pdfextra/README.md +++ b/macros/luatex/optex/pdfextra/README.md @@ -1,6 +1,7 @@ # PDF Extra -PDF Extra provides extra PDF features for OpTeX. +PDF Extra provides extra PDF features for OpTeX (or in limited form for plain +LuaTeX and LuaLaTeX). As a minimalistic package OpTeX doesn't support "advanced" features of PDF file format in the base. This third party package aims to provide them. Summary of @@ -21,13 +22,18 @@ well as technical documentation interleaved with source code. # Installation instructions -Put `pdfextra.opm` where `optex` can find it. +Put `pdfextra.opm` where your TeX can find it. Additionaly, for plain/LaTeX you +need `pdfextra.tex`, and on top of that `pdfextra.sty` for LaTeX. Or just copy paste anything you want. # Usage -In OpTex do: `\load [pdfextra]`. +In OpTeX do: `\load [pdfextra]`. + +In plain LuaTeX do: `\input pdfextra`. + +In LuaLaTeX do: `\usepackage{pdfextra}`. # License diff --git a/macros/luatex/optex/pdfextra/examples/pdfextra-example-latex.tex b/macros/luatex/optex/pdfextra/examples/pdfextra-example-latex.tex new file mode 100644 index 0000000000..dc5a31f9f1 --- /dev/null +++ b/macros/luatex/optex/pdfextra/examples/pdfextra-example-latex.tex @@ -0,0 +1,223 @@ +% Compiled with: +% env TEXMFDOTDIR='..//:~/src/texlive/texmf-dist/source/latex/media9/files/' lualatex pdfextra-example-latex.tex +\documentclass{article} + +\usepackage{hyperref} +\usepackage{xcolor} +\usepackage{graphicx} +\usepackage{pdfextra} +\sdef{_linkcolor}{\color{blue}} + +\begin{document} + +% Using document level JavaScript we can run initialization code right at the +% start (this is more flexible than \openaction). +\dljavascript[random]{ + function getRandomNumber() { + return 4; % chosen by fair dice roll, ![https://xkcd.com/221/] + } + console.println("initialized with seed " + getRandomNumber()); +} + + + +% For external references we need to `\filedef` "external" and "url" files +% beforehand: +\filedef/u[doc-internet]{http://petr.olsak.net/ftp/olsak/optex/optex-doc.pdf} +\filedef/x[doc-local]{optex-doc.pdf} + +% We then try to reference them using external references: +\hlink[extref:doc-internet:ref:langphrases]{OpTeX documentation, section ``Multilingual phrases and quotation marks''.} +\hlink[extpgref:doc-internet:12]{OpTeX documentation, page 12.} + + + +% Insert a video twice with different settings: +\filedef/e[video]{example-movie.mp4} +% Insert video into page using Renditions mechanism with controls and autoplay. +\render[video][ + controls=true, + aactions=\renditionautoplay, +]{\includegraphics[width=\textwidth]{example-image.pdf}} + +% We set red text color, blue border (RGB triplet) for "rendition" links. +\sdef{_renditionlinkcolor}{\color{red}} +\sdef{_renditionborder}{0 1 0} +% Then we add some buttons. +\hlink[rendition::play]{play} \hlink[rendition::pause]{pause} +\hlink[rendition::stop]{stop} \hlink[rendition::resume]{resume} + +% Render the same file again, but with different dimensions, no controls +% and explicit activation. +\render[video]{\includegraphics{example-image.pdf}} +% This one can't have buttons, because it doesn't have its own name -- "video" +% is used by the previous one. + + + +% Add already embedded video to the list of attachments shown in user +% interface. +\attach[video] + + +% We are done for this page, who not go to the next one? +% +% \hlink typesets in group, so we locally disable lining links (our button is +% bigger than normal line) +\hlink[named:NextPage]{\nolininglinks\scalebox{2}[2]{NEXT PAGE}} + + + +\clearpage + + + +% Deliver fresh random number to everyone who sees this page using "page open" +% ("O") trigger event of page's actions. +\pageactions[ + {O} {js:{app.alert("Random number for you is " + getRandomNumber());}} +] + + +% Link to previous page (predefined PDF action) with "Split" transition: +\hlink[named:PrevPage, transition:Split]{Go to previous page (with transition).} + + + +\clearpage + +% A 3D Rich Media annotation with a custom view and script follows: + +% First we define the 3D file, so we can use same name for the view and have it +% auto included. +\filedef/e[example]{pdfextra-example-part.prc} + +% Then a simplistic "front" view. +\DDDview[example][ + projection=ortho, + roo=400, +] + +% A 3D JavaScript script that will define function to use with action button. +% (we write the script only now, so we don't have to carry around an extra file +% in the package, you would normally have the contents in the file -- "turn.js" +% in this case). +\newwrite\js +\immediate\openout\js=turn.js +% rotate every node by angle degrees along $x$ axis +\immediate\write\js{\detokenize{ +function turn(angle) { + angle = angle * Math.PI / 180; + for (var i = 0; i < scene.nodes.count; i++) { + var node = scene.nodes.getByIndex(i); + node.transform.rotateAboutXInPlace(angle); + } +} +}} +\closeout\js + +% The annotation itself, with our script above. +\RM[example][ + activation=auto, + scripts=turn.js, +]{\textcolor{white}{\vrule width\textwidth height\textwidth}} + +\hlink[js:\DDDcontext{example}.turn(10);]{Turn by 10 degrees along $x$ axis.}\par +\hlink[js:\DDDcontext{example}.turn(30);]{Turn by 30 degrees along $x$ axis.}\par +\hlink[js:\DDDcontext{example}.turn(90);]{Turn by 90 degrees along $x$ axis.} + + + +\clearpage + + +% Here is the "epix" 3D model example from media9 documentation ported to +% pdfextra. +% +% First we define a view with the same name as the future Rich Media +% annotation. This view will then automatically be used if no `views` key is +% specified. No need to be excessive with decimal numbers. +\DDDview[epix][ + FOV=30, + c2c=4 2 3, + coo=4.41 2.19 0, + roo=430, +] + +% 3Dmenu is used often, lets use shortcut instead. +\filedef/e[3dmenu]{3Dmenu.js} +% We want to use the nice "epix" name for the view and annotation. +\filedef/e[epix]{epix.prc} + +% Just to spice things up, we diverge a bit from media9 and define custom +% background color. We can't use LaTeX's colors, so we use RGB triplet. +\newcommand{\GreyBG}{0.9 0.9 0.9} + +% Define the 3D Rich Media annotation. One view is automatically detected from +% name ("epix"). Scripts will run in specified order at initialization time +% (when the annotation is activated). +\RM[epix][ + scripts={ + asylabels.js, + 3Dspintool.js, + 3dmenu, + }, + background=\GreyBG, +]{\includegraphics[width=0.8\textwidth, height=0.8\textwidth]{epixposter.pdf}} + + + +\clearpage + + + +% Second media9 example is "dice" it has a lot of views, but they are simple. +% This time we can't use the view name deduction from `\RM` name -- there is +% more than one view. +\DDDview[Front][roo=27] +\DDDview[Back][roo=27, c2c=0 1 0] +\DDDview[Left][roo=27, c2c=-1 0 0] +\DDDview[Right][roo=27, c2c=1 0 0] +\DDDview[Top][roo=27, c2c=0 0 1] +\DDDview[Bottom][roo=27, c2c=0 0 -1] +\DDDview[Fish Eye at Centre][fov=120] + +% We want to use all the defined views, as well as autoactivate the annotation. +% This means that the preview mostly sets dimensions, because it will not be +% shown much. (Only in viewers that don't support 3D Rich Media -- that is, all +% except Acrobat). +\RM[dice.u3d][ + views={Front, Back, Left, Right, Top, Bottom, Fish Eye at Centre}, + activation=auto, + scripts=3dmenu, +]{\textcolor{red}{\vrule height.5\textwidth width.5\textwidth}} + +% A few buttons for switching views. +\hlink[goto3dview::/N]{\frame{Next view}} +\hlink[goto3dview::(Back)]{\frame{View ``Back''}} +\hlink[goto3dview::5]{\frame{6th view in the list}} + +\clearpage + + +% Last media9 example ported. It has its own JavaScript file for animation, +% which can be customized at runtime using JavaScript actions that access 3D +% context of the annotation. +\filedef/e[malte]{malte.u3d} +\DDDview[malte][c2c=1 1 1, roo=0.25] +\RM[malte][ + activation=auto, + scripts={3dmenu, malte.js}, +]{\textcolor{blue}{\vrule height 0.5\textwidth width 0.5\textwidth}} + +% Normal JavaScript actions, but we access functions defined globaly in the 3D +% JavaScript context of "malte" Rich Media annotation. +\hlink[js:\DDDcontext{malte}.cntrClockWise();] {\includegraphics[height=1.44em]{boutona.pdf}} +\hlink[js:\DDDcontext{malte}.pause();] {\includegraphics[height=1.44em]{boutonb.pdf}} +\hlink[js:\DDDcontext{malte}.clockWise();] {\includegraphics[height=1.44em]{boutonc.pdf}} +\hlink[js:\DDDcontext{malte}.scaleSpeed(1/1.1);]{\includegraphics[height=1.44em]{boutond.pdf}} +\hlink[js:\DDDcontext{malte}.origSpeed();] {\includegraphics[height=1.44em]{boutone.pdf}} +\hlink[js:\DDDcontext{malte}.scaleSpeed(1.1);] {\includegraphics[height=1.44em]{boutonf.pdf}} + + +\end{document} diff --git a/macros/luatex/optex/pdfextra/examples/pdfextra-example.pdf b/macros/luatex/optex/pdfextra/examples/pdfextra-example.pdf Binary files differindex abb2e9c4c5..24ca714a75 100644 --- a/macros/luatex/optex/pdfextra/examples/pdfextra-example.pdf +++ b/macros/luatex/optex/pdfextra/examples/pdfextra-example.pdf diff --git a/macros/luatex/optex/pdfextra/examples/pdfextra-example.tex b/macros/luatex/optex/pdfextra/examples/pdfextra-example.tex index 6093bf7def..6704ac4b98 100644 --- a/macros/luatex/optex/pdfextra/examples/pdfextra-example.tex +++ b/macros/luatex/optex/pdfextra/examples/pdfextra-example.tex @@ -7,17 +7,14 @@ % env TEXMFDOTDIR=.:~/src/texlive/texmf-dist/source/latex/media9/files/ optex pdfextra-example.tex % \endtt -% basic \OpTeX/ settings +% Basic \OpTeX/ settings: \enlang\enquotes \fontfam[lm] -%\pdfobjcompresslevel=0 -%\pdfcompresslevel=0 - -% load the package from standard search path +% Load the package from standard search path: \load[pdfextra] -% Before using \hlink we must activate hyperlinks +% Before using \hlink we must activate hyperlinks: \hyperlinks\Blue\Green % Maybe we want to greet the user and jump to page 2 right at the start? @@ -41,7 +38,8 @@ -% For external references we need to `\filedef` "external" and "url" files beforehand: +% For external references we need to `\filedef` "external" and "url" files +% beforehand: \filedef/u[doc-internet]{http://petr.olsak.net/ftp/olsak/optex/optex-doc.pdf} \filedef/x[doc-local]{optex-doc.pdf} @@ -53,20 +51,24 @@ % Insert a video twice with different settings: \filedef/e[video]{example-movie.mp4} -% insert video into page using Renditions mechanism with controls and autoplay +% Insert video into page using Renditions mechanism with controls and autoplay. \render[video][ controls=true, aactions=\renditionautoplay, ]{\picwidth=\hsize \inspic{example-image.pdf}} -% Maybe add action buttons? +% We set red text color, blue border (RGB triplet) for "rendition" links. +\let\_renditionlinkcolor\Red +\def\_renditionborder{0 1 0} +% Then we add some buttons. \hlink[rendition::play]{play} \hlink[rendition::pause]{pause} \hlink[rendition::stop]{stop} \hlink[rendition::resume]{resume} % Render the same file again, but with different dimensions, no controls % and explicit activation. \render[video]{\inspic{example-image.pdf}} -% This one can't have buttons, because it doesn't have its own name ("video") is used by the previous one. +% This one can't have buttons, because it doesn't have its own name -- "video" +% is used by the previous one. @@ -87,13 +89,13 @@ -% deliver fresh random number to everyone who sees this page using "page open" -% trigger event of page's actions +% Deliver fresh random number to everyone who sees this page using "page open" +% ("O") trigger event of page's actions. \pageactions[ {O} {js:{app.alert("Random number for you is " + getRandomNumber());}} ] -% "previous page" link with "Split" transition +% Link to OpTeX's page reference ("pg:1") with "Split" transition: \hlink[pg:1, transition:Split]{Go to previous page (with transition).} @@ -102,7 +104,8 @@ % A 3D Rich Media annotation with a custom view and script follows: -% First we define the 3D file, so we can use same name for the view and have it auto included. +% First we define the 3D file, so we can use same name for the view and have it +% auto included. \filedef/e[example]{pdfextra-example-part.prc} % Then a simplistic "front" view. @@ -112,7 +115,9 @@ ] % A 3D JavaScript script that will define function to use with action button. -% (we write the script only now, so we don't have to carry around an extra file in the package) +% (we write the script only now, so we don't have to carry around an extra file +% in the package, you would normally have the contents in the file -- "turn.js" +% in this case). \newwrite\js \immediate\openout\js=turn.js % rotate every node by angle degrees along $x$ axis @@ -131,7 +136,7 @@ function turn(angle) { \RM[example][ activation=auto, scripts=turn.js, -]{{\White\vrule width\hsize height\hsize}} +]{\White\vrule width\hsize height\hsize} \hlink[js:\DDDcontext{example}.turn(10);]{Turn by 10 degrees along $x$ axis.}\par \hlink[js:\DDDcontext{example}.turn(30);]{Turn by 30 degrees along $x$ axis.}\par @@ -142,10 +147,11 @@ function turn(angle) { \vfil\break -% Here is the "epix" 3D model example from media9 documentation ported to pdfextra +% Here is the "epix" 3D model example from media9 documentation ported to +% pdfextra. % % First we define a view with the same name as the future Rich Media -% annotation. This view will then automatically be used if no `views` is +% annotation. This view will then automatically be used if no `views` key is % specified. No need to be excessive with decimal numbers. \DDDview[epix][ FOV=30, @@ -159,11 +165,13 @@ function turn(angle) { % We want to use the nice "epix" name for the view and annotation. \filedef/e[epix]{epix.prc} -% Just to spice things up, we diverge a bit from media9 and define custom background color. +% Just to spice things up, we diverge a bit from media9 and define custom +% background color. \colordef\GreyBG{0.1\Black} % Define the 3D Rich Media annotation. One view is automatically detected from -% name ("epix"). Scripts will run in turn at initialization time. +% name ("epix"). Scripts will run in specified order at initialization time +% (when the annotation is activated). \RM[epix][ scripts={ asylabels.js, @@ -180,7 +188,8 @@ function turn(angle) { % Second media9 example is "dice" it has a lot of views, but they are simple. -% This time we can't use the deduction with same name. +% This time we can't use the view name deduction from `\RM` name -- there is +% more than one view. \DDDview[Front][roo=27] \DDDview[Back][roo=27, c2c=0 1 0] \DDDview[Left][roo=27, c2c=-1 0 0] @@ -190,38 +199,32 @@ function turn(angle) { \DDDview[Fish Eye at Centre][fov=120] % We want to use all the defined views, as well as autoactivate the annotation. -% This means that the previews mostly sets dimensions, because it will not be -% shown much. (Except in viewers that don't support 3D Rich Media -- all except -% Acrobat). +% This means that the preview mostly sets dimensions, because it will not be +% shown much. (Only in viewers that don't support 3D Rich Media -- that is, all +% except Acrobat). \RM[dice.u3d][ views={Front, Back, Left, Right, Top, Bottom, Fish Eye at Centre}, activation=auto, scripts=3dmenu, -]{{\Red \vrule height.5\hsize width.5\hsize}} +]{\Red \vrule height.5\hsize width.5\hsize} % A few buttons for switching views. \hlink[goto3dview::/N]{\frame{Next view}} \hlink[goto3dview::(Back)]{\frame{View \"Back"}} \hlink[goto3dview::5]{\frame{6th view in the list}} -% And define the action buttons using this new custom action. -\hlink[diceview:/N]{Next view} -\hlink[diceview:(Back)]{View \"Back"} -\hlink[diceview:5]{6th view in the list} - - \vfil\break % Last media9 example ported. It has its own JavaScript file for animation, % which can be customized at runtime using JavaScript actions that access 3D -% conotext. +% context of the annotation. \filedef/e[malte]{malte.u3d} \DDDview[malte][c2c=1 1 1, roo=0.25] \RM[malte][ activation=auto, scripts={3dmenu, malte.js}, -]{{\Blue \vrule height.5\hsize width0.5\hsize}} +]{\Blue \vrule height.5\hsize width0.5\hsize} {\picheight=1.44em % Normal JavaScript actions, but we access functions defined globaly in the 3D @@ -240,7 +243,7 @@ function turn(angle) { % Lastly a showcase of transitions / page durations in \OpTeX/ slideshow. % Because transitions are displayed only in fullscreen mode, we could request -% it by using "\fullscreen". But we have more pages before this, so we didn't. +% it by using `\fullscreen`. But we have more pages before this, so we didn't. % We just turn the rest of the document into slideshow. \slides @@ -253,7 +256,8 @@ function turn(angle) { % "Wipe" and be 1 second long. \transitions[Wipe:1] -% The slides will by default be shown for 3 seconds before advancing to the next one. +% The slides will by default be shown for 3 seconds before advancing to the +% next one. \defaultpageduration[3] % But the first slide has override to only be shown for 1 second. \pageduration[1] @@ -268,7 +272,7 @@ function turn(angle) { % to that page. That means that we probably didn't see the "Wipe:1" animation % of the first slide, because we already were there. However, this second slide % with "Fade" is now shown correctly. (The first one also will, when we go -% back.) +% back to it.) \transition[Fade] \sec First slide diff --git a/macros/luatex/optex/pdfextra/pdfextra-doc.pdf b/macros/luatex/optex/pdfextra/pdfextra-doc.pdf Binary files differindex e5a6b8e30d..9534e46bfa 100644 --- a/macros/luatex/optex/pdfextra/pdfextra-doc.pdf +++ b/macros/luatex/optex/pdfextra/pdfextra-doc.pdf diff --git a/macros/luatex/optex/pdfextra/pdfextra-doc.tex b/macros/luatex/optex/pdfextra/pdfextra-doc.tex index 38f6cd9795..292bb34ab2 100644 --- a/macros/luatex/optex/pdfextra/pdfextra-doc.tex +++ b/macros/luatex/optex/pdfextra/pdfextra-doc.tex @@ -2,8 +2,6 @@ \load [doc, pdfextra] \catcode`\.=11 -\hyperlinks\Green\Green - % table notes (http://petr.olsak.net/optex/optex-tricks.html#tnote) \newcount\tnotenum \def\tnotelist{} @@ -14,22 +12,23 @@ \global\tnotenum=0 \gdef\tnotelist{}% } -% use `\hlink` instead of OpTeX `\*link` s -\protected\def\_link[#1]#2#3{\hlink[#1]{#3}} -\protected\def\_ilink[#1]#2{\hlink[#1]{#2}} -\protected\def\_ulink[#1]#2{\hlink[url:#1]{#2}} -\public \link \ilink \ulink ; - \let\_cslinkcolor\Blue % allow hyperlinking of \OpTeX's control sequences (see doc.opm) -\let\_pdfextra_opdocaction\_pdfextra_urlaction -\let\_pdfextra_opdoclinkcolor\Blue +\let\_pdfextra_extdocaction\_pdfextra_urlaction +\let\_extdoclinkcolor\Blue \def\_Xindex#1#2{\sdef{,#1}{}\slet{el:#1}{optexdoclink}} -\def\optexdoclink{\hlink[opdoc:\optexdocurl\#cs:\_tmpa]{\csstring\\\_tmpb}} +\def\optexdoclink{\hlink[extdoc:\optexdocurl\#cs:\_tmpa]{\csstring\\\_tmpb}} \def\optexdocurl{http://petr.olsak.net/ftp/olsak/optex/optex-doc.pdf} \isfile{optex-doc.eref}\iftrue \input{optex-doc.eref}\fi +% allow hyperlinks to TeX's control sequences (TeX in a Nutshell) +\def\Xeref#1{\sdef{,#1}{}\slet{el:#1}{texdoclink}} +\def\texdoclink{\hlink[extdoc:\texdocurl\#cs:\_tmpa]{\csstring\\\_tmpb}} +\def\texdocurl{http://petr.olsak.net/ftp/olsak/optex/tex-nutshell.pdf} +\isfile{tex-nutshell.eref}\iftrue \input{tex-nutshell.eref}\fi + + \insertoutline{PDF extra} \tit PDF extra -- extra PDF features for \OpTeX/ @@ -50,7 +49,8 @@ copying some useful parts of this package into your documents / packages. \OpTeX/ namespacing is used, but it can be easily stripped, if you wish to incorporate these macros into other macro packages. The code currently depends on \LuaTeX/, but mostly uses only pdf\TeX/ primitives and a few simple macros -from \OpTeX/. +from \OpTeX/. Additionally, the package can be used in plain LuaTeX and +LuaLaTeX (in a limited form), see section~\ref[user:plain+latex]. User documentation (`pdfextra-doc.tex`) and technical documentation interleaved with source code (`pdfextra.opm`) are all typeset in this PDF file. Some @@ -367,7 +367,7 @@ macros like `\ref` or `\url` might be beneficial. <text> will be typeset directly and the area it occupies will be clickable. Clicking it executes action defined by <action spec>. Line breaks inside <text> will be possible, in that case several clickable rectangles will be created, one for each line. -Normally in text you want the ares to be of the same height and depth +Normally in text you want the areas to be of the same height and depth (calculated from `\baselineskip`), to achieve sort of a lining, uniform effect. If you want to define big clickable buttons, you may need to turn off the lining effect using \^`\nolininglinks`. It respects groups, but a counterpart @@ -482,7 +482,7 @@ must be unique) and are executed in order of definition. Use \begtt \adef![#1]{\url{#1}} \filedef/e[preamble]{preamble.js} -\djavascript[preamble]{preamble} +\dljavascript[preamble]{preamble} \dljavascript[initialization]{% var data = 42; @@ -554,7 +554,7 @@ Examples: \render[video]{\inspic{example-image.pdf}} % we want the rendition action to have yellow border and red content -\let\_renditionborder\Yellow +\def\_renditionborder{1 1 0} \let\_renditionlinkcolor\Red To start playing the video, click \hlink[rendition::play]{\"Play"}. @@ -671,14 +671,102 @@ You can choose what is shown when document is opened with commands: The commands are mutually exclusive and only the first appearing one will be respected. -You can set request two page view (odd pages on the right) using +You can request two page view (odd pages on the right) using \^`\duplexdisplay`. It is useful for more natural display of double sided documents. Because it may not be desirable to automatically apply this, it is independent of `\margins`. +\label[user:plain+latex] +\sec Usage in plain \LuaTeX/ or LuaLa\TeX/ + +You can use this package also from plain LuaTeX by adding to your document: + +\begtt +\input pdfextra +\endtt + +\noindent or for LuaLa\TeX/: + +\begtt +\usepackage{pdfextra} +\endtt + +See the file `pdfextra-example-latex.tex` for the adaptation of the \OpTeX/ +examples to \LaTeX/. + +The usage of the macros described in this document is the same, but there are +limitations: + +\begitems +* {\em Color}. Where this package expects \"\OpTeX/ color" key value argument +(e.g. `\Blue`), you have to use an RGB triplet instead (e.g. `0.0 0.0 0.0` or +the shorter `0 0 0`). + +But for text color setting, you can get away with wrapping commands from +La\TeX/'s `color` package, e.g. to customize link border/color: + + \begtt + \sdef{_renditionlinkcolor}{\color[red]} + \endtt + +* {\em Initialization}. In \OpTeX/ you normally have to initialize hyperlinks +with the command\nl +`\hyperlinks<color for internal links><color for external links>`.\nl +This is not required by this package. You can instead set the color by setting +`\_linkcolor` (fallback for all link types), `\_ilinkcolor` / `\_elinkcolor` +(internal / external links). E.g. if you have the \LaTeX/ `color` package +loaded, you can get blue links like this: + + \begtt + \sdef{_linkcolor}{\color[blue]} + \endtt + +In addition to the above this means all links will be blue except \"rendition" +links. + +* {\em Openaction}. If the package `hyperref` is used, then `\openaction` will +not work. + +* {\em Labels / hyperlink destinations}. \OpTeX/ uses very simple and consistent +scheme for labels / hyperlink destinations: + + \begitems + * `ref:<label>` -- result of `\label[<label>]` + * `toc:<tocrefnum>` -- result of `\chap`/`\sec`/`\secc` titles + * `pg:<gpageno>` -- created on each page with global numbering from 1 + * `cite:<bibpart>/<bibnum>` -- bibliography references, + * `fnt:<gfnotenum>` -- link form text to footnote + * `fnf:<gfnotenum>` -- link from footnote to text + * `url:<url>` -- used by `\url` or `\ulink`, + \enditems + + Hence these labels / destinations can be used with `\hlink`, e.g. to make text + `page 5` a link to page 5, one can use: + + \begtt + \hlink[pg:5]{page 5} + \endtt + + This is not possible in plain \LuaTeX/ (no destinations are created) or + LuaLa\TeX/ (different and incompatible destination names). You would have to + create your own destinations adhering to the naming convention + `<type>:<arguments>` to be able to use `\hlink` as intended for some links. + +\enditems + \chap Technical documentation -\printdoctail pdfextra.opm +This is the technical documentation. It is intended for those who want to know +how this package works internally. Casual users shouldn't need to read this. But +if you would like to customize anything or perhaps just use some part of this +package, feel free to copy paste and use anything you want in \OpTeX/'s spirit. + +This documentation is interleaved within the source itself, both are contained +in a single file, `pdfextra.opm` (according to \OpTeX/ conventions). The user +documentation is instead contained in `pdfextra-doc.tex`, which itself +`\input`'s the documented source file `pdfextra.opm` so that the user and +technical documentation is available in a single PDF file, `pdfextra-doc.pdf`. + \printdoc pdfextra.opm \bye diff --git a/macros/luatex/optex/pdfextra/pdfextra.opm b/macros/luatex/optex/pdfextra/pdfextra.opm index b7cf70a981..bccf096484 100644 --- a/macros/luatex/optex/pdfextra/pdfextra.opm +++ b/macros/luatex/optex/pdfextra/pdfextra.opm @@ -1,17 +1,35 @@ % vim: tw=80 -\_def\_pdfextra_version{0.1} +\_def\_pdfextra_version{0.2} \_codedecl \RM {Extra PDF features (v\_pdfextra_version)} +\_namespace{pdfextra} + \_doc \sec Package initialization + We ensure that hyperlinking is active. Our fallback \`\_linkcolor` must + exist. We also use it for `\hyperlinks` if the user didn't enable + `\hyperlinks` yet (we don't want to override user setting). + \_cod + +\_ifdefined\_ilinkcolor\_else + \_ifdefined\_linkcolor + \_ea\_let\_ea\_linkcolor \_ifdefined\Blue\Blue\_else\_empty\_fi + \_else + \_let\_linkcolor\linkcolor + \_fi +\_fi + +\_ifx\_dest\_destactive\_else + \_hyperlinks\_linkcolor\_linkcolor +\_fi + + \_doc We are in the \OpTeX/ package namespace. A couple of shortcuts are defined here: \`\.isdefined`, \`\.trycs`, \`\.cs` \`\.slet`, \`\.slet`, \`\.sdef` and - \`\.xdef`. They all hard code the package name, because we already have too + \`\.sxdef`. They all hard code the package name, because we already have too many levels of indirection. \_cod -\_namespace{pdfextra} - \_def\.isdefined#1{\_isdefined{_pdfextra_#1}} \_def\.trycs#1{\_trycs{_pdfextra_#1}} \_def\.cs#1{\_cs{_pdfextra_#1}} @@ -67,7 +85,8 @@ \_doc \`\.xaddto``\macro`{<text>} is a natural extension of \OpTeX's `\addto` that - expands <text> and is global. + expands <text> and is global.\nl + \`\.tmp` is used throught the package for temporary values. \_cod \_def\.xaddto#1#2{\_edef\.tmp{#2}% @@ -115,10 +134,6 @@ rough estimate we take the current page~-- this actually works well for slides where page breaks are manual. - `\.pageof` is expandable, but we want to let the user know, that the document - needs to be processed twice. Therefore we use \LuaTeX's - `\immediateassignment` to increment the counter of unresolved references. - When `.ref` file is read along with the defintion of `\.Xpageof` this package has not been loaded yet. Hence we can't use namespaced variants of `\.isdefined`, etc. @@ -134,7 +149,6 @@ \_def\.pageof#1{% \.trycs{pageof:#1}{% - \_immediateassignment\_incr\_unresolvedrefs \_the\_numexpr\_gpageno+1\_relax % best effort = current page num }% } @@ -368,14 +382,12 @@ \_doc \label[actions-link] \secc Link annotations - The main use of actions~-- annotations of `/Subtype /Link`. - Annotation of this type creates an active rectangular area on the page that - executes a PDF action (or chain of them in the general case). - \`\hlinkactive``[<action spec>]<text>` is a natural extension of \OpTeX/'s - `\linkactive`, that supports the classic \"jump" actions of types `ref`, - `bib`, etc. But also other types of actions. No distinction between - \"internal" (`\ilink`) and external (`\ulink`) links is made. The mechanism is - completely generic. + The main use of actions~-- annotations of `/Subtype /Link`. Annotation of + this type creates an active rectangular area on the page that executes a PDF + action (or chain of them in the general case). + \`\hlink``[<action spec>]<text>` is macro that typesets <text> and makes area + occupied by it active according to <action spec>. All action types are + supported, the mechanism is completely generic. The `\pdfstartlink`/`\pdfendlink` primitives are used to denote the part of the page where <text> appears as active. \LuaTeX/ will then handle even the @@ -383,7 +395,7 @@ multiple rectangular annotations to cover all `\hbox`es). \_cod -\_def\.hlinkactive[#1]#2{\_bgroup\_def\#{\_csstring\#}% +\_def\.hlink[#1]#2{\_bgroup\_def\#{\_csstring\#}% \_edef\.type{\.pdfactiontype[#1]}% \_quitvmode\_pdfstartlink \.linkdimens attr{\_pdfborder{\.type}}% @@ -391,25 +403,25 @@ \_localcolor\.linkcolor{\.type}#2\_pdfendlink\_egroup } +\_nspublic \hlink ; + \_doc - `\hlinkactive` itself is dormant before `\hyperlinks` occurs. Until then, a - dummy \`\hlink` is used. \OpTeX/'s `\hyperlinks` is extended to hook `\hlink` - activation. The colors of internal/external links are remembered for - compatibility with \OpTeX/. + Use `\hlink` as the backing command for OpTeX's \"higher level" linking + commands (`\ilink` and `\ulink`). + + The lower level ones (`\xlink` and its predecessor `\link` actually have + completely different semantics with regards to color, so we keep them as they + are. \_cod -\_def\.hlink[#1]#2{\_quitvmode{#2}} -\_nspublic \hlink ; +\_protected\_def\_ilink[#1]#2{\.hlink[#1]{#2}} +\_protected\_def\_ulink[#1]#2{{\_escapechar=-1 \_ea}\_expanded + {\_noexpand\.hlink[url:\_detokenize{#1}]}{#2}} -\_let\.oldhyperlinks\_hyperlinks -\_def\_hyperlinks#1#2{% - \.oldhyperlinks#1#2 - \_let\.ilinkcolor=#1% - \_let\.elinkcolor=#2% - \_let\.hlink=\.hlinkactive - \_let\hlink=\.hlink -} -\_public \hyperlinks ; +\_public \link \ilink \ulink ; + +%\_protected\_def\_link[#1]#2#3{\_hlink[#1]{#3}} +%\_protected\_def\_xlink#1#2#3#4{\_hlink[#1:#2]{#4}} \_doc Two customizations of `\hlinks` are possible: @@ -421,10 +433,12 @@ running text~-- it covers all space of a line using `\baselineskip`. \`\nolininglinks` sets no dimensions, this is useful for buttons, that may have larger height/depth than a line. - * The color is determined from the type of link (that is the first action in - <action spec>) by checking `\_<type>linkcolor` (compatible with \OpTeX/) or - `\_pdfextra_<type>linkcolor`. - As a fallback \`\.ilinkcolor` is used (set by `\hyperlinks`). + * The color is determined from the type of link (that is, the first action in + <action spec>) by checking `\_<type>linkcolor` (compatible with \OpTeX/). + As a fallback `\_ilinkcolor` is used (set by \OpTeX's `\hyperlinks`) for all links + except for URLs, where `\_elinkcolor` is used instead. If even these + fallback colors are not defined (`\hyperlinks` isn't used), then the most + generic `\_linkcolor` will be taken or no color will be set. \enditems \_cod @@ -436,8 +450,10 @@ \_nspublic \lininglinks \nolininglinks ; -\_def\.linkcolor#1{\_trycs{_#1linkcolor}{\.trycs{#1linkcolor}{\.ilinkcolor}}} -\_def\.ilinkcolor{} +\_def\.linkcolor#1{\_trycs{_#1linkcolor}{\_trycs{_ilinkcolor}{\_trycs{_linkcolor}{}}}} + + % \_urllinkcolor = \_elinkcolor with fallbacks +\_def\_urllinkcolor{\.linkcolor{e}} \_doc \secc Open action @@ -683,7 +699,8 @@ \.pdfpageattributesetters Dur \defaultpageduration \pageduration {#1} \_doc - \sec Attachments and document level JavaScript + \label[nametrees] + \sec Name trees -- attachments and document level JavaScript These don't have any last place to be in, so they are documented separately, here. Attaching files using `/FileAttachment` annotations: @@ -711,7 +728,7 @@ \`\dljavascript``[<name>]{<script>}` (adds action that executes <script> after document is opened, <name> is more or less meaningless). - Internally both commands construct lists of what ends up in the resulting name + Internally the commands construct lists of what ends up in the resulting name array, i.e. pairs {\visiblesp `(<name>) <object number> 0 R `}. Intermediate macros \`\.embeddedfiles` and \`\.dljavascripts` are used for this. @@ -735,7 +752,23 @@ \_nspublic \dljavascript ; \_doc - Object creation, which is common to both, is handled by\nl\indent + Renditions (see \ref[mm-renditions]) also need their name tree. This package + mostly doesn't play well with Unicode filenames, that is why they are + forbidden. However, Renditions that are accessed from JavaScript have to be + named/present in a `/Renditions` name tree, with the names encoded in the PDF + encoding (UTF-16BE).\nl + The names and object references are collected in \`\.renditions`. Unicode + encoding is hacked with \`\.pdfstringtounicode`. + \_cod + +\_def\.pdfstringstrip(#1){#1}% +\_def\.pdfstringtounicode#1#2{% + \_ea\_pdfunidef\_ea#1\_ea{\_ea\.pdfstringstrip\_expanded{\.cs{filename:#2}}}% +} +\_def\.renditions{} + + \_doc + Object creation, which is common to all name trees, is handled by\nl\indent \`\.makenamearray``<name tree name><name tree content>`.\nl It doesn't do anything for empty lists, to not bloat PDF files when this mechanism isn't used. @@ -750,12 +783,13 @@ The lists themselves can only be written out to the PDF file at the very end of the run. We use \OpTeX/'s `\_byehook`, which is run in `\_bye`. But `\bye` itself may be predefined by the user, for example when using some of the - \OpTeX/ tricks. We just hope that user keeps `\_byehook`. + \OpTeX/ tricks. We just hope that the user keeps `\_byehook`. \_cod \_addto\_byehook{% \.makenamearray{EmbeddedFiles}\.embeddedfiles \.makenamearray{JavaScript}\.dljavascripts + \.makenamearray{Renditions}\.renditions } \_doc @@ -889,6 +923,7 @@ \_def\.boxedannot[#1:#2]#3#4#5{% \_setbox0=\_hbox{#3}\_setbox2=\_null \_ht2=\_ht0 \_wd2=\_wd0 \_dp2=\_dp0 + \_preshipout0 \box0 \_immediate\_pdfxform0 % box with annotation both stretching to dimensions of appearance \_hbox{\.setpageof{#1:#2}% @@ -995,9 +1030,10 @@ \_ea\_readkv\_ea{\_ea\.renderdefaults\_ea,\_the\_opt}% \.colortorgbdef\.bgcolor{\_kv{background}}% % rendition object ("media specifaction") + \.pdfstringtounicode\.uiname\.name \_pdfobj {<</Type /Rendition /S /MR - /N \.cs{filename:\.name} + /N \.uiname /C <<%/Type /MediaClip /S /MCD % subtype MediaClipData /D \.cs{filespec:\.name} @@ -1011,6 +1047,7 @@ /BE << /O \_kv{opacity} /B [\.bgcolor] >> >> >>}\_pdfrefobj\_pdflastobj + \.xaddto\.renditions{\.uiname \_the\_pdflastobj \_space 0 R }% \.redefinename{rendition}% \.sxdef{rendition:\.name}{\_the\_pdflastobj}% % screen annotation ("screen space allocation") @@ -1284,7 +1321,7 @@ \_doc For scripting using JavaScript actions one needs to access the 3D context of the 3D / Rich Media annotation. This requires the page number. We can't use - `this.pageNum` from [TODO], because the script strictly doesn't have to be on + `this.pageNum`, because the script strictly doesn't have to be on the same page. We use `\.pageof` (`\.setpageof` was done in `\.boxedannot`) to retrieve the page number in next run. Also PDF indexes page numbers from 0. \`\DDDannot``{<name>}`. and \`\DDDcontext``{<name>}` allow this. @@ -1593,12 +1630,12 @@ coo=0 0 0, c2c=0 -1 0, } -\.sdef{3dview:media9}{\_edef\.coo{\_kv{coo}}\_edef\.c2c{\_kv{c2c}}\_edef\.viewparams{ +\.sdef{3dview:media9}{\_edef\.viewparams{ /MS /M /C2W [\_directlua{ local function normalize(x, y, z) local len = math.sqrt(x*x + y*y + z*z) - if len ~= 0 then return x/len, y/len, z/len else return 0, 0, 0 end + if len \csstring\~= 0 then return x/len, y/len, z/len else return 0, 0, 0 end end local function cross(ux, uy, uz, vx, vy, vz) return uy*vz - uz*vy, uz*vx - ux*vz, ux*vy - uy*vx @@ -1689,14 +1726,3 @@ \_endnamespace \_endcode - -This is the technical documentation. It is intended for those who want to know -how this package works internally. Casual users shouldn't need to read this. But -if you would like to customize anything or perhaps just use some part of this -package, feel free to copy paste and use anything you want in \OpTeX/'s spirit. - -This documentation is interleaved within the source itself, both are contained -in a single file, `pdfextra.opm` (according to \OpTeX/ conventions). The user -documentation is instead contained in `pdfextra-doc.tex`, which itself -`\input`'s the documented source file `pdfextra.opm` so that the user and -technical documentation is available in a single PDF file, `pdfextra-doc.pdf`. diff --git a/macros/luatex/optex/pdfextra/pdfextra.sty b/macros/luatex/optex/pdfextra/pdfextra.sty new file mode 100644 index 0000000000..2ebe8354c5 --- /dev/null +++ b/macros/luatex/optex/pdfextra/pdfextra.sty @@ -0,0 +1,4 @@ +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{pdfextra} + +\input pdfextra diff --git a/macros/luatex/optex/pdfextra/pdfextra.tex b/macros/luatex/optex/pdfextra/pdfextra.tex new file mode 100644 index 0000000000..cbbeca0c17 --- /dev/null +++ b/macros/luatex/optex/pdfextra/pdfextra.tex @@ -0,0 +1,364 @@ +\ifdefined \pdfextraloaded \expandafter \endinput \fi +\chardef\pdfextraloaded=\catcode`\_ +\catcode`\_=11 + +\long\def \_xargs #1#2{\ifx #2;\else + \expandafter#1\expandafter#2\expandafter\_xargs \expandafter #1\fi} + +\def \_private {\_xargs \_privateA} +\def \_privateA #1{\expandafter\let\csname _\csstring #1\endcsname#1} + +% primitives +\_private \detokenize \expanded \hbox \ht \wd \dp \copy \immediateassignment ; +\_private \escapechar \baselineskip \quitvmode \lastnamedcs ; + +% +% prefixed.opm +% + +\_private \expandafter \def \let \ifx \else \fi \undefined \wlog \endinput ; + +\_let\_ea=\_expandafter + +\_def \_codedecl #1#2{% + \_ifx #1\_undefined \_wlog{#2}% + \_else \_ea \_endinput \_fi +} + +\_let \_endcode = \_endinput + +\_def \_wterm {\_immediate \_write16 } + +\_private \ifcsname \csname \endcsname \errmessage \gdef \csstring \directlua ; +\_let \_ea = \_expandafter + +% modified +\_def \_pkglabel{} +\_def\_namespace #1{% + \_ifcsname namesp:#1\_endcsname \_errmessage + {The name space "#1" is used already, it cannot be used twice}% + \_endinput + \_else \_resetnamespace{#1}\_fi +} +\_def\_resetnamespace #1{% + \_ea \_gdef \_csname namesp:#1\_endcsname {}% + \_gdef \_pkglabel{_#1}% + \_directlua{ + luatexbase.add_to_callback("process_input_buffer", + function (str) + return string.gsub(str, "\_nbb[.]([a-zA-Z])", "\_nbb _#1_\_pcent 1") + end, "_namespace") + }% +} +% modified +\_def\_endnamespace {% + \_directlua{ luatexbase.remove_from_callback("process_input_buffer", "_namespace") }% + \_gdef \_pkglabel{}% +} + +\_def \_nspublic {\_xargs \_nspublicA} +\_def \_nspublicA #1{% + \_unless\_ifx #1\_undefined + \_opwarning{\_ea\_ignoreit\_pkglabel\_space redefines the meaning of \_string#1}\_fi + \_ea\_let \_ea#1\_csname \_pkglabel _\_csstring #1\_endcsname +} + +% modified +\_def \_public {\_xargs \_publicA} +\_def \_publicA #1{\_ea\_let \_ea#1\_csname _\_csstring #1\_endcsname} + +% +% basic-macros.opm +% + +\_private \bgroup \egroup \empty \space \null \long ; + +\_long\_def \_ignoreit #1{} +\_long\_def \_useit #1{#1} +\_long\_def \_ignoresecond #1#2{#1} +\_long\_def \_usesecond #1#2{#2} + +\_private \the \inputlineno \edef ; + +\_def \_opwarning #1{\_wterm{WARNING l.\_the\_inputlineno: pdfextra: #1.}} + +\_edef \_bslash {\_csstring\\} +\_edef \_pcent {\_csstring\%} +\_edef \_nbb {\_bslash\_bslash} + +\_private \xdef \begincsname ; + +\_def \_sdef #1{\_ea\_def \_csname#1\_endcsname} +\_def \_sxdef #1{\_ea\_xdef \_csname#1\_endcsname} +\_def \_slet #1#2{\_ea\_let \_csname#1\_ea\_endcsname + \_ifcsname#2\_ea\_endcsname \_begincsname#2\_endcsname \_else \_undefined \_fi +} + +% Make \sdef public, so users can customize without messing with catcodes. +\_public \sdef ; + +\_def \_cs #1{\_csname#1\_endcsname} +\_def \_trycs#1#2{\_ifcsname #1\_endcsname \_csname #1\_ea\_endcsname \_else #2\_fi} + +\_long\_def \_addto #1#2{\_ea\_def\_ea#1\_ea{#1#2}} + +\_private \global \advance ; + +\_def\_incr #1{\_global\_advance#1by1 } +\_def\_decr #1{\_global\_advance#1by-1 } + +\_private \immediate \closeout \jobname ; + +% modified +\_def\_byehook{% + \_immediate\_closeout\_reffile + \_edef\_tmp{\_mdfive{\_jobname.ref}}% + \_ifx\_tmp\_prevrefhash\_else \_opwarning{Try to rerun, + \_jobname.ref file was \_ifx\_prevrefhash\_empty created\_else changed\_fi}\_fi +} + +% +% alloc.opm +% + +\_private \newcount ; + +% +% if-macros.opm +% + +\_def\_afterfi#1#2\_fi{\_fi#1} + +\_private \unless ; + +\_def\_isdefined #1#2{\_ifcsname #1\_endcsname \_else \_ea\_unless \_fi #2} + +\_private \newread \openin \relax \ifeof \closein ; + +\_newread \_testin +\_def\_isfile #1{% + \_immediate\_openin\_testin ={#1}\_relax + \_ifeof\_testin \_ea\_unless + \_else \_immediate\_closein\_testin + \_fi +} + +\_private \begingroup \toks \endgroup \futurelet ; + +\_long\_def\_isnextchar#1#2#3{\_begingroup\_toks0={\_endgroup#2}\_toks1={\_endgroup#3}% + \_let\_tmp= #1\_futurelet\_next\_isnextcharA +} +\_def\_isnextcharA{\_the\_toks\_ifx\_tmp\_next0\_else1\_fi\_space} + +% +% more-macros.opm +% + +\_private \string \newtoks \romannumeral ; + +\_def\_optdef#1[#2]{% + \_def#1{\_opt={#2}\_isnextchar[{\_cs{_oA:\_string#1}}{\_cs{_oB:\_string#1}}}% + \_sdef{_oA:\_string#1}[##1]{\_opt={##1}\_cs{_oB:\_string#1\_nospaceafter}}% + \_sdef{_oB:\_string#1\_nospaceafter}% +} +\_def\_nospaceafter#1{\_ea#1\_romannumeral-`\.} +\_newtoks\_opt + +\_private \noexpand \catcode \toksapp ; + +\_newtoks\_tmptoks +% modified +\_edef\_tmp{\_noexpand\_catcode`!=\_the\_catcode`! \_noexpand\_catcode`?=\_the\_catcode`?} +\_catcode`!=3 \_catcode`?=3 +\_def\_replstring #1#2#3{% \replstring #1{stringA}{stringB} + \_long\_def\_replacestringsA##1#2{\_tmptoks{##1}\_replacestringsB}% + \_long\_def\_replacestringsB##1#2{\_ifx!##1\_relax \_else \_toksapp\_tmptoks{#3##1}% + \_ea\_replacestringsB\_fi}% + \_ea\_replacestringsA #1?#2!#2% + \_long\_def\_replacestringsA##1?{\_tmptoks{##1}\_edef#1{\_the\_tmptoks}}% + \_ea\_replacestringsA \_the\_tmptoks} +\_tmp % modified + +% modified (no \_skiptoeol) +\_long\_def\_doc #1\_cod{} + +% +% keyval.opm +% + +\_def\_readkv#1{\_ea\_def\_ea\_tmpb\_ea{#1}% + \_replstring\_tmpb{= }{=}\_replstring\_tmpb{ =}{=}% + \_replstring\_tmpb{, }{,}\_replstring\_tmpb{,,}{,}% + \_ea \_kvscan \_tmpb,,=,} +\_def\_kvscan #1#2=#3,{\_ifx#1,\_else \_sdef{_kv:#1#2}{#3}\_ea\_kvscan\_fi} +\_def\_kv#1{\_trycs{_kv:#1}{\_kvunknown}} +\_def\_kvunknown{???} + +% +% ref-file.opm +% + +\_private \newwrite \write \iftrue \iffalse \input ; + +% modified +\_newwrite\_reffile +\_def\_inputref {% + \_isfile{\_jobname.ref}\_iftrue + \_edef\_prevrefhash{\_mdfive{\_jobname.ref}}% + \_input {\_jobname.ref}% + \_openref + \_fi +} + +\_private \luaescapestring ; + +% modified +\_def\_mdfive#1{\_directlua{ + local fh = io.open("\_luaescapestring{#1}", "rb") + if fh then + local data = fh:read("*a") + fh:close() + tex.print(md5.sumhexa(data)) + end +}} +\_def\_prevrefhash{} + +\_def\_wrefrelax#1#2{} +\_let\_wref=\_wrefrelax + +\_private \openout ; + +% modified +\_def\_openref {% + \_immediate\_openout\_reffile={\_jobname.ref}\_relax + \_gdef\_wref ##1##2{\_write\_reffile{\_bslash\_csstring##1##2}}% + \_immediate\_write\_reffile {\_pcent\_pcent\_space pdfextra - REF file}% + \_gdef\_openref{}% +} +\_def\_ewref #1#2{\_edef\_ewrefA{#2}\_ea\_wref\_ea#1\_ea{\_ewrefA}} + +\_private \ifnum ; + +\_def\_refdecl{\_bgroup \_catcode`\#=12 \_refdeclA} +\_def\_refdeclA #1{\_egroup\_openref + \_immediate\_write\_reffile {\_pcent\_space \_string \refdecl:}% + \_immediate\_write\_reffile {\_detokenize{#1}}% +} + +% +% hyperlinks.opm +% + +\_def\_pdfborder#1{\_ifcsname _#1border\_endcsname + /C [\_csname _#1border\_endcsname] /Border [0 0 .6]\_else /Border [0 0 0]\_fi +} + +% modified +\_def\_hyperlinks#1#2{% + \_let\_ilinkcolor=#1\_empty + \_let\_elinkcolor=#2\_empty +} +\_public \hyperlinks ; + +% +% pdfuni-string.opm +% + +% modified +\_def\_pdfunidef#1#2{% + \_edef\_tmp{#2}% + \_def#1{\_directlua{ + local str = token.scan_string() + local out = { "<FEFF" } + for _, c in utf8.codes(str) do + if c < 0x10000 then + out[\_csstring\#out+1] = string.format("\_pcent04X", c) + else + c = c - 0x10000 + local high = c >> 10 + 0xD800 + local low = c \_csstring\& 0x3FF + 0xDC00 + out[\_csstring\#out+1] = string.format("\_pcent04X\_pcent04X", high, low) + end + end + out[\_csstring\#out+1] = ">" + tex.print(table.concat(out, ""))}\_ea{\_tmp}% +}} + +% +% optex.lua +% + +\_private \setbox ; + +% modified +\_def\_preshipout#1#2{\_setbox#1#2} + +% +% luatex-ini.opm +% + +\_private \protected \pdfextension \pdffeedback \pdfvariable ; +\_private \numexpr \saveboxresource \lastsavedboxresourceindex ; + +\_protected\_def \_pdfobj {\_pdfextension obj } +\_protected\_def \_pdfrefobj {\_pdfextension refobj } +\_protected\_def \_pdflastobj {\_numexpr\_pdffeedback lastobj\_relax} +\_protected\_def \_pdfstartlink {\_pdfextension startlink } +\_protected\_def \_pdfendlink {\_pdfextension endlink\_relax} +\_protected\_def \_pdfcatalog {\_pdfextension catalog } +\_protected\_edef\_pdfpageattr {\_pdfvariable pageattr} +\_protected\_def \_pdfnames {\_pdfextension names } +\_protected\_def \_pdfannot {\_pdfextension annot } +\_protected\_def \_pdflastannot {\_numexpr\_pdffeedback lastannot\_relax} + \_def \_pdfpageref {\_pdffeedback pageref} + \_let \_pdfxform \_saveboxresource + \_let \_pdflastxform \_lastsavedboxresourceindex + +% +% output.opm +% + +\_let\_oldshipout=\shipout +\_def\shipout{\_begoutput\_oldshipout} + +% modified +\_newcount\_gpageno +\_def \_begoutput{\_incr\_gpageno + % we try \folio, or nothing ({}), pdfextra only uses \gpageno + \_immediate\_wref\_Xpage{{\_the\_gpageno}{\_trycs{folio}{}}}% +} + +% +% references.opm +% + +% modified +\_def\_Xpage#1#2{\_def\_currpage{{#1}{#2}}} + +% +% colors.opm +% + +% modified +\_let\_localcolor\_relax + +% +% \_byehook and \_inputref +% + +\_private \ifdefined ; + +\_ifdefined\AtEndDocument + % make sure all pages (and write whatsits) are flushed before we close files + \AtEndDocument{\clearpage\_byehook}% +\_else + % hope that usual \bye (\outer\def\bye{\par\vfill\supereject\end}) is used + \_let\_end\end + \_def\end{\_byehook \_end}% +\_fi + +\_inputref + +% continue with the real macros +\_input pdfextra.opm +\_catcode`\_=\pdfextraloaded |