diff options
author | Norbert Preining <norbert@preining.info> | 2017-07-13 10:25:48 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2017-07-13 10:25:48 +0900 |
commit | cfe306ba1b7ec40855a300580b7981845d56edeb (patch) | |
tree | e2feaf2adf8a8afe43a995528097913793874d01 /texmf-dist/source/latex/aeb-pro/aeb_pro.dtx | |
parent | 32d0671418a3cc6ad0465b06539ed54d96f77784 (diff) |
add aeb-mlink aeb-pro aebxmp graphicxsp annot-pro
Diffstat (limited to 'texmf-dist/source/latex/aeb-pro/aeb_pro.dtx')
-rw-r--r-- | texmf-dist/source/latex/aeb-pro/aeb_pro.dtx | 4903 |
1 files changed, 4903 insertions, 0 deletions
diff --git a/texmf-dist/source/latex/aeb-pro/aeb_pro.dtx b/texmf-dist/source/latex/aeb-pro/aeb_pro.dtx new file mode 100644 index 00000000..3cde5508 --- /dev/null +++ b/texmf-dist/source/latex/aeb-pro/aeb_pro.dtx @@ -0,0 +1,4903 @@ +%\iffalse +%<*copyright> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% aeb_pro.sty package, %% +%% Copyright (C) 2006--2017 D. P. Story %% +%% dpstory@acrotex.net %% +%% %% +%% 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{aeb_pro} +%<package> [2017/03/08 v2.8a aeb_pro: A support package (dps)] +%<*driver> +\documentclass{ltxdoc} +\usepackage[colorlinks,hyperindex=false]{hyperref} +\pdfstringdefDisableCommands{\let\\\textbackslash} +\def\CMD#1{\textbackslash{#1}}\def\EXCL{!} +\let\opt\texttt \let\app\textsf \let\pkg\textsf \let\env\texttt +\OnlyDescription % comment out for implementation details +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\bgroup\ttfamily +\gdef\brpr#1{\char123\relax#1\char125\relax}\egroup +\let\darg\brpr +\let\env\texttt +\let\opt\texttt +\let\app\textsf +\def\visispace{\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}}}} +\InputIfFileExists{aebdocfmt.def}{\PackageInfo{aeb_pro}{Inputting aebdocfmt.def}} + {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax + \PackageInfo{aeb_pro}{aebdocfmt.def cannot be found}} +\begin{document} + \GetFileInfo{aeb_pro.sty} + \title{aeb\_pro\\as suggested by J\"{u}rgen Gilg} + \author{D. P. Story\\ + Email: \texttt{dpstory@acrotex.net}} + \date{processed \today} + \maketitle + \tableofcontents + \DocInput{aeb_pro.dtx} +\IfFileExists{\jobname.ind}{\newpage\setupFullwidth\par\PrintIndex}{\paragraph*{Index} The index goes here.\\Execute + \texttt{makeindex -s gind.ist -o aeb\_pro.ind aeb\_pro.idx} on the command line and recompile + \texttt{aeb\_pro.dtx}.} +\IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of changes goes here.\\Execute + \texttt{makeindex -s gglo.ist -o aeb\_pro.gls aeb\_pro.glo} on the command line and recompile + \texttt{aeb\_pro.dtx}.} +\end{document} +%</driver> +% \fi +% \MakeShortVerb{|} +% \InputIfFileExists{aebdonotindex.def}{\PackageInfo{aeb_pro}{Inputting aebdonotindex.def}} +% {\PackageInfo{aeb_pro}{cannot find aebdonotindex.def}} +% +% \begin{macrocode} +% Begin package segment +%<*package> +% \end{macrocode} +% \changes{v1.9}{2016/03/03}{Allow users of pdftex and xetex to access JavaScript related +% methods provided they use \string\textsf{Acrobat} as their PDF reader.} +% \changes{v2.5}{2016/08/31}{Revised \string\texttt{aeb\_pro.js} to include +% \string\texttt{aebDocSaveAs()}.} +% +% \section{Introduction} +% +% The \pkg{aeb\_pro} package that access the `advanced' features of the PDF +% specification. It uses various combinations of driver-dependent code, +% \textbf{pdfmark} code, and JavaScript methods and techniques that require +% \app{Acrobat~7.0 Professional} for document assembly. The package provides +% the \textbf{AeB Control Central}. Use the \textbf{AeB Control Central} to +% load all your Acro\negthinspace\TeX packages in the correct order. See +% additional remarks in the titled paragraph \textbf{\nameref{para:beast}} +% below. +% +% \section{Declare Options} +% +% We declare some options for this package. +%\changes{v2.2}{2016/07/26}{Removed the generation of \string\texttt{fsprodef.js} from the INS file.} +% \begin{macrocode} +\RequirePackage{ifpdf}[2006/02/20] +\RequirePackage{ifxetex}[2006/08/21] +\RequirePackage{xkeyval} +% \end{macrocode} +% Some standard flags used by this package. +% \begin{macrocode} +\let\aebp@One=1 \let\aebp@Zero=0 +\let\aebp@YES=y \let\aebp@NO=n +% \end{macrocode} +% \subsection{AeB Control Central} +% +% \noindent\IndexOpt{web}^^A +% \IndexOpt{exerquiz}^^A +% \IndexOpt{dljslib}^^A +% \IndexOpt{eforms} +% \IndexOpt{insdljs}^^A +% \IndexOpt{eq2db}\par +% \IndexOpt{aebxmp}^^A +% \IndexOpt{hyperref}^^A +% \IndexOpt{graphicxsp}^^A +% \IndexOpt{rmannot}^^A +% \vskip-\baselineskip\noindent AeB control central +% is simply a set of options for including the +% other members of the AeB family. This assures that the package are +% loaded in the correct order. +% The values of each of these option +% keys are the options of the packages they reference. +% \par\medskip\noindent +% (2016/12/09) Incorporate the version argument into package specification, for example, +%\begin{verbatim} +% \usepackage[web={designi,forpaper,req=2016/11/03}]{aeb_pro} +%\end{verbatim} +% The version takes a key of \texttt{req}, as shown above. +% \changes{v0.8f}{2008/06/15}{Added \textsf{graphicxsp} to the list of support packages} +% \changes{v2.7}{2016/12/10}{Incorporate the version argument into package specification} +% \par\medskip\noindent +% \cs{ap@csarg} is a convenience macro for working with command names. +% \begin{macrocode} +\def\ap@csarg#1#2{\expandafter#1\csname#2\endcsname} +% \end{macrocode} +% Define an \pkg{xkeyval} family \texttt{aebpreq} with a single key \IndexKey{req}\texttt{req}. Later, we +% use this key to separate package options from the key-value \texttt{req=\ameta{release date}}. +% \begin{macrocode} +\define@key{aebpreq}{req}[]{\def\eq@pkgReq{#1}} +% \end{macrocode} +% A convenience command to save the value of package for later use. +% \begin{macrocode} +\def\aebp@setCCOptions#1#2{%#1=package #2=options + \ap@csarg\edef{aeb@#1@opts}{#2}} +% \end{macrocode} +% We not define options for \pkg{aeb\_pro} of \texttt{web}, \texttt{exerquiz}, \texttt{eforms}, \texttt{insdljs}, +% \texttt{eq2db}, \texttt{aebxmp}, \texttt{hyperref}, \texttt{graphicxsp}, and \texttt{rmannot}. +% \begin{macrocode} +\@tfor\aeb@pcks:={web}{exerquiz}{dljslib}% +{eforms}{insdljs}{eq2db}{aebxmp}{hyperref}{graphicxsp}{rmannot}\do +{% + \ap@csarg\let{aeb@\aeb@pcks @req}\@empty + \ap@csarg\let{aeb@\aeb@pcks @opts}\relax + \edef\aeb@pack@def{\noexpand + \define@key{aeb_pro.sty}{\aeb@pcks}[]{% + \noexpand\aebp@setCCOptions{\aeb@pcks}{##1}}% + }\aeb@pack@def +} +% \end{macrocode} +% We provide a convenient way to pass the \texttt{driver}\IndexOpt{driver} used, \texttt{dvips} or +% \texttt{dvipsone}. If the user chooses the \opt{web} option, then he/she might +% have a \texttt{web.cfg} file, so using this option may not be +% needed, in this case. +% \begin{macrocode} +\let\aebp@passDriver\aebp@YES +\ifpdf\let\aebp@passDriver\aebp@NO\else +\ifxetex\let\aebp@passDriver\aebp@NO\fi\fi +\define@choicekey+{aeb_pro.sty}{driver}% + {dvipsone,dvips,pdftex,dvipdfm,textures,% + dvipdfmx,xetex}{% + \def\aeb@driver{#1}\ifx\aeb@driver\@empty\else + \PassOptionsToPackage{#1}{web} + \PassOptionsToPackage{#1}{exerquiz} +\def\aebp@PassToHYIns{\PassOptionsToPackage{#1}{hyperref} + \PassOptionsToPackage{#1}{insdljs}} +\ifx\aebp@passDriver\aebp@YES + \expandafter\aebp@PassToHYIns\fi + \PassOptionsToPackage{#1}{eforms} + \PassOptionsToPackage{#1}{graphicxsp} + \fi +}{\PackageError{aeb_pro}{Bad choice for the driver, permissible values + \MessageBreak are dvipsone, dvips, pdftex, dvipdfm, + textures,\MessageBreak dvipdfmx, and xetex} + {Try again with a permissible driver name}} +\let\aeb@driver\@empty +% \end{macrocode} +% +% \paragraph*{On the nature of the beast}\label{para:beast} There are three types of commands +% (and environments) in this package: (1) commands that use driver dependent +% code, available to all workflows; (2) commands that depend on the +% \textbf{pdfmark} operator, available only to the \app{dvips/Distiller} +% workflow; and (3) commands that use `post-PDF creation' methods that rely +% on the document author having the full \app{Acrobat} application. +% +% For the workflow \app{dvips/Distiller}, all three code types are +% available; for whose authors that prefer \app{pdflatex/\penalty0 +% lualatex/\penalty0 xelatex}, but \emph{do not have} the full +% \texttt{Acrobat} product, the commands of type~(1) are available through +% the \opt{nopro} option. Finally, for authors that prefer +% \app{pdflatex/\penalty0 lualatex/\penalty0 xelatex} and \emph{do have} +% \app{Acrobat}, the commands of type~(1) and~(3) are available through +% the \opt{useacrobat} option. + +% \subsection{The \texttt{useacrobat} option} +% +% If the document author has \app{Acrobat}, but wants to use +% \app{pdflatex}, \app{xelatex}, etc, we shall let them but under +% restricted conditions using the \opt{useacrobat}\IndexOpt{useacrobat} option. +% Essentially, all of \pkg{aeb\_pro} is available except for any commands that use +% layers; hence, the \opt{uselayers} and \opt{ocganime} options are not supported. +% \begin{macrocode} +\newif\if@useacrobat \@useacrobatfalse +\DeclareOptionX{useacrobat}{\@useacrobattrue} +% \end{macrocode} +% +% \subsection{\texttt{nopro} option} +% +% The normally \pkg{aeb\_pro} will brings in all the +% code that would require the use of the \app{Distiller} and \app{Acrobat Pro}, +% this is the default. The \opt{nopro}\IndexOpt{nopro} option gives +% access, for non-\app{Distiller} workflows, to the \textbf{AeB Control Center} and to all commands that do +% no involve layers or post-PDF creation methods. +% \begin{macrocode} +\newif\if@gopro \@goprotrue +\DeclareOptionX{nopro}{\@useacrobattrue\@goprofalse + \PassOptionsToPackage{nopro}{insdljs}} +% \end{macrocode} +% \paragraph*{Input \texttt{aebpro.def}} We input \texttt{aebpro.def} at the end of the package. +% \begin{macrocode} +\def\aeb@InputAeBPro{\InputIfFileExists{aebpro.def}% + {\PackageInfo{aeb_pro}{Inputting code for the pro option}}% + {\PackageInfo{aeb_pro}{Cannot find aebpro.def. + Reinstall or refresh your file name database, as needed.}}} +\AtEndOfPackage{\aeb@InputAeBPro} +% \end{macrocode} +% +% \subsection{\texttt{uselayers} option} +% The \texttt{uselayers}\IndexOpt{uselayers} option activates the use of +% Optional Content Groups, a.k.a., layers. +% \begin{macrocode} +\let\aebp@uselayers=0 +\DeclareOptionX{uselayers}{% + \ifx\aebp@uselayers0\AtEndOfPackage{\aeb@InputAeBLayers}% + \global\let\aebp@uselayers=1\fi +} +\def\aeb@InputAeBLayers{\InputIfFileExists{aeblayers.def}% + {\PackageInfo{aeb_pro}{Inputting code for uselayers option}}% + {\PackageInfo{aeb_pro}{Cannot find aeblayers.def. + Reinstall or refresh your file name database.}}} +% \end{macrocode} +% +% \subsection{\texttt{gopro} option} +% Some of the components of AeB have the pro option. Use \texttt{gopro}\IndexOpt{gopro} to +% pass the \texttt{pro} option to all components that take it. +% \begin{macrocode} +\DeclareOptionX{gopro}{\PassOptionsToPackage{pro}{web}} +% \end{macrocode} +% \subsection{\texttt{attachsource} option} +% A simple interface, \texttt{attachsource}\IndexOpt{attachsource} to attaching the source file(s) of \cs{jobname}. +% \begin{macrocode} +\DeclareOptionX{attachsource}{\def\aeb@attachsource{#1}} +\let\aeb@attachsource\@empty +% \end{macrocode} +% \subsection{\texttt{attachments} option} +% The \texttt{attachments}\IndexOpt{attachments} option is a general routine +% for attaching files other than the \cs{jobname}. +% \begin{macrocode} +\DeclareOptionX{attachments}{\def\aeb@attachments{#1}} +\let\aeb@attachments\@empty +% \end{macrocode} +% \changes{v1.4}{2013/02/24}{Support for optional attachments} +% The two options, \texttt{optattachments}\IndexOpt{optattachments} and \texttt{!optattachments}\IndexOpt{!optattachments}, +% set the Booleaqn switch \cs{ifoptattachments} to true or false, respectively. +% the default is false. When the command \cs{prjInput} is used, files are input into +% the source file, but also attached to the PDF when \texttt{optattachments} is used, and not +% attached when \texttt{!optattachments} is used. +% \begin{macrocode} +\newif\ifoptattachments\optattachmentsfalse +\newif\ifoptattachmentsTaken\optattachmentsTakenfalse +\DeclareOptionX{optattachments}{% + \optattachmentsTakentrue + \optattachmentstrue} +\DeclareOptionX{!optattachments}{% + \optattachmentsTakentrue + \optattachmentsfalse} +% \end{macrocode} +% \subsection{The \texttt{linktoattachments} option} +% The option \texttt{linktoattachments}\IndexOpt{linktoattachments} is a +% general routine for linking to attached PDF files. +% \begin{macrocode} +\def\@aeb@InputUnicodes{\InputIfFileExists{unicodes.def}% + {\typeout{aeb_pro: Inputting code for the linktoattachments option}}% + {\typeout{aeb_pro: Cannot find unicodes.def. + Reinstall or refresh your file name database, as needed.}}} +\let\aeb@InputUnicodes\@empty +% \end{macrocode} +% \changes{v1.7k}{2015/08/06}{Added code so that the childof is read after linktoattachments} +% (2015/08/06) Added code so that the childof is read after linktoattachments +% \changes{v2.4}{2016/08/03}{Removed the \string\texttt{latin1} option as unworkable across some workflows} +% \begin{macrocode} +\DeclareOptionX{linktoattachments}{% + \let\aeb@InputUnicodes\@aeb@InputUnicodes} +\let\aeb@childofInput\@empty +\let\aeb@childof\@empty +\DeclareOptionX{childof}{\def\aeb@childof{#1}\def\aeb@childofInput{% + \InputIfFileExists{\aeb@childof_xref.cut}{}{}}} +\def\inputAttachmentRelatedFiles{% + \aeb@InputUnicodes + \aeb@childofInput +} +\AtEndOfPackage{\inputAttachmentRelatedFiles} +% \end{macrocode} +% When the \texttt{ocganime}\IndexOpt{ocganime} option is taken, the code for ocg animation is included. +% \begin{macrocode} +\let\inputCommonAnimeCode\relax +\DeclareOptionX{ocganime}{% + \ifx\aebp@uselayers0\ExecuteOptionsX{uselayers} + \global\let\aebp@uselayers=1\fi + \ifx\inputCommonAnimeCode\relax + \let\inputCommonAnimeCode\aebp@inputCommonAnimeCode + \AtEndOfPackage{\inputCommonAnimeCode}\fi + \AtEndOfPackage{\inputOcgAnimeCode} +} +% \end{macrocode} +% When the \texttt{btnanime}\IndexOpt{btnanime} option is taken, the code for button animation is included. +% \begin{macrocode} +\DeclareOptionX{btnanime}{% + \ifx\inputCommonAnimeCode\relax + \let\inputCommonAnimeCode\aebp@inputCommonAnimeCode + \AtEndOfPackage{\inputCommonAnimeCode}\fi + \AtEndOfPackage{\inputBtnAnimeCode} +} +\def\inputBtnAnimeCode{\InputIfFileExists{btnnanime.def} + {\PackageInfo{aeb_pro}{inputting btnnanime.def}} + {\PackageWarning{aeb_pro}{cannot find btnnanime.def}}}% +\def\inputOcgAnimeCode{\InputIfFileExists{ocganime.def} + {\PackageInfo{aeb_pro}{inputting ocganime.def}} + {\PackageWarning{aeb_pro}{cannot find ocganime.def}}}% +\def\aebp@inputCommonAnimeCode{\InputIfFileExists{anime_support.def} + {\PackageInfo{aeb_pro}{inputting anime_support.def}} + {\PackageWarning{aeb_pro}{cannot find anime_support.def}}}% +% \end{macrocode} +% We allow for a configuration file, usually of the form +%\begin{verbatim} +% \ExecuteOptionsX{driver=<driver>} % dvips, dvipsone, pdftex, xetex +%\end{verbatim} +% For the last two, \app{AeB Pro} can only act as a central control of +% the \app{AeB} Family. +% \changes{v1.7}{2015/06/12}{Added a test for \texttt{pdftex} and \texttt{xetex}} +% If the driver being used (automatically detected) is \texttt{pdftex} or \texttt{xetex}, we +% use the \texttt{nopro} option and don't input \texttt{aebpro.cfg}. +% \begin{macrocode} +\let\pathToBtnCtrlIcons\@empty +\let\ExecuteOptionsXSAVE\ExecuteOptionsX +\let\ExecuteOptionsX\@gobble +\InputIfFileExists{aebpro.cfg}{}{} +\let\ExecuteOptionsX\ExecuteOptionsXSAVE +\ifpdf\ExecuteOptionsX{driver=pdftex}\else + \ifxetex\ExecuteOptionsX{driver=xetex}\else + \@ifundefined{l@tex@@@@driver}{\ExecuteOptionsX{driver=dvips}} + {\ExecuteOptionsX{driver=dvipsone}}\fi\fi +% \end{macrocode} +% \paragraph*{Process the options} +% \begin{macrocode} +\ProcessOptionsX +\edef\ap@restoreCats{% + \catcode`\noexpand\"=\the\catcode`\"\relax + \catcode`\noexpand\,=\the\catcode`\,\relax + \catcode`\noexpand\(=\the\catcode`\(\relax + \catcode`\noexpand\!=\the\catcode`\!\relax +} +\@makeother\"\@makeother\,\@makeother\(\@makeother\! +% \end{macrocode} +% \paragraph*{Set up variables} +% We set a switch to indicate we are using the \textbf{pdfmark} operator or not. +% Initially we assume so. +% \changes{v1.9}{2016/03/03}{Set up \string\cs{ifpdfmark} switch earlier} +% \begin{macrocode} +\@ifundefined{ifpdfmarkup}{\newif\ifpdfmarkup}{} +\pdfmarkuptrue +% \end{macrocode} +%\changes{v2.2}{2016/07/26}{Added support for luatex .85} +% Added support for luatex .85. Moved this code to \pkg{insdljs} (2016/07/31); \pkg{aeb\_pro} requires +% \pkg{insdljs} so put it there. +%\begin{verbatim} +% \ifpdf\ifx\pdffeedback\@undefined\else +% \def\pdfpageref{\pdffeedback pageref}\fi\fi +%\end{verbatim} +% Set the variables for the case of \opt{dvips} and \opt{dvipsone}. +% \changes{v1.9}{2016/03/03}{Modified driver check, adding \string\cs{@useacrobattrue}} +% \begin{macrocode} +\def\aeb@testdriver{dvips}% +\ifx\aeb@testdriver\aeb@driver + \@useacrobattrue\else +\def\aeb@testdriver{dvipsone}% +\ifx\aeb@testdriver\aeb@driver + \@useacrobattrue\else +% \end{macrocode} +% If not \texttt{dvips} or \texttt{dvipsone}, the user is +% not to use the \textbf{pdfmark} operator. +% \changes{v1.9}{2016/03/03}{Mark as non-pdfmark} +% \begin{macrocode} + \pdfmarkupfalse +\fi\fi +% \end{macrocode} +% \paragraph*{Summary of switch settings} +% \begin{itemize} +% \item \app{Distiller} workflow: \cs{pdfmarkuptrue}, \cs{@useacrobatrue}, \cs{@goprotrue} +% \item non-\app{Distiller}/non-\app{Acrobat} workflow (the \opt{nopro} option): +% \cs{pdfmarkupfalse}, \cs{@useacrobatrue}, \cs{@goprofalse} +% \item non-\app{Distiller}/\app{Acrobat} workflow (the \opt{useacrobat} option): +% \cs{pdfmarkupfalse}, \cs{@useacrobatrue}, \cs{@goprotrue} +% \end{itemize} +% Some options are not valid when using the \opt{nopro}, such as attachments. +% \begin{macrocode} +\if@gopro\else +\let\aebp@isattach\aebp@NO +\ifx\aeb@attachsource\@empty\else\let\aebp@isattach\aebp@YES\fi +\ifx\aeb@attachments\@empty\else\let\aebp@isattach\aebp@YES\fi + \let\aeb@attachsource\@empty + \let\aeb@attachments\@empty + \optattachmentsfalse\optattachmentsTakenfalse + \let\inputAttachmentRelatedFiles\relax +\ifx\aebp@isattach\aebp@YES + \PackageWarningNoLine{aeb_pro}{The various attachment options + are not\MessageBreak supported with the nopro option, + ignoring them}\fi +\fi +% \end{macrocode} +% \paragraph*{Disallow some options that use the \textsf{pdfmark}} +% We do what we say. +% \begin{macrocode} +\ifpdfmarkup\else +\if\aebp@uselayers1 + \def\aeb@InputAeBLayers{\PackageError{aeb_pro} + {The uselayers and ocganime options are not supported,\MessageBreak + with the useacrobat and nopro options,\MessageBreak + ignoring these options}{Remove dependence on layers, + or obtain\MessageBreak the full Acrobat product}} + \let\texHelpIndicator\@gobble + \let\addJStexHelpEnter\@gobble + \let\addJStexHelpExit\@gobble + \let\texHelp\@gobbletwo + \def\xBld#1\eBld{} + \let\defineRC\@gobbletwo + \let\insertRC\@gobble + \let\definePR\@gobbletwo + \let\insertPR\@gobble + \let\proofRollovers\relax + \let\texPHProof\@gobbletwo + \newcommand\animeBld[1][]{} + \def\DeclareAnime#1#2#3{} + \newcommand\backAnimeBtn[3][]{} + \newcommand\clearAnimeBtn[3][]{} + \newcommand\forwardAnimeBtn[3][]{} +\fi\fi +% \end{macrocode} +% +% \section{Package requirements} +% +% AeB builds on the \textsf{web} package to a certain extent, +% hence requires \textsf{insdljs}. +% \begin{macrocode} +\def\aebp@PkgWarningi#1{\ifpdfmarkup\else\PackageWarningNoLine{aeb_pro} + {The #1\space package requires Adobe Distiller,\MessageBreak + do not load this package}\fi} +\def\aebp@PkgWarningii#1{\PackageWarningNoLine{aeb_pro} + {The #1\space package requires Adobe Distiller,\MessageBreak + ignoring #1\space as an option}} +\def\aebp@PkgWarningiii#1{\PackageWarningNoLine{aeb_pro} + {The #1\space package requires Adobe Distiller or\MessageBreak + the useacrobat option (Acrobat required),\MessageBreak + ignoring #1\space as an option}} +\providecommand\getargsii[2]{\def\aeb@argi{#1}\def\aeb@argii{#2}} +% \end{macrocode} +% \cs{ap@RP} is a command that computes the appropriate +% \cs{PassOptionsToPackage} and \cs{RequiredPackage} commands +%\begin{verbatim} +% #1 aeb_pro required options, #2 = package name +%\end{verbatim} +% \begin{macrocode} +\newcommand\ap@RP[2][]{\def\@rgi{#1}\def\@rgii{#2}% + \ifx\@rgi\@empty\else\edef\@rgi{[\@rgi]}\fi + \@ifnextchar[%] + {\ap@@RP}{\ap@@RP[]}} +% \end{macrocode} +% \cs{ap@@RP} continues \cs{ap@RP} and is the one that formulates +% \cs{PassOptionsToPackage} and \cs{RequiredPackage} commands +%\begin{verbatim} +% #1 = aeb_pro required date +%\end{verbatim} +% \begin{macrocode} +\def\ap@@RP[#1]{\def\@rgiii{#1}% + \let\XKV@rm\@empty\let\eq@pkgReq\@empty + \@ifundefined{aeb@\@rgii @opts} + {\ifx\@rgi\@empty\else + \ap@csarg\edef{aeb@\@rgii @req}{#1}\fi + }{% +% \end{macrocode} +% Calculate \cs{PassOptionsToPackage} and its arguments +% \begin{macrocode} + \edef\x{\noexpand + \setkeys*{aebpreq}{\@nameuse{aeb@\@rgii @opts}}}\x + \edef\eq@theseOpts{\XKV@rm}% + \ap@csarg\edef{aeb@\@rgii @req}{\eq@pkgReq}% + \edef\x{\noexpand + \PassOptionsToPackage{\eq@theseOpts}{\@rgii}}\x + }% +% \end{macrocode} +% Construct \cs{RequirePackage} and its arguments +% \begin{macrocode} + \ifx\@rgiii\@empty + \if!\@nameuse{aeb@\@rgii @req}!\else + \ap@csarg\edef{aeb@\@rgii @req}{[\@nameuse{aeb@\@rgii @req}]}\fi + \else + \@ifl@t@r{#1}{\@nameuse{aeb@\@rgii @req}}% + {\if!\@nameuse{aeb@\@rgii @req}!\else + \ap@csarg\edef{aeb@\@rgii @req}% + {[\@nameuse{aeb@\@rgii @req}]}\fi + }{\ap@csarg\edef{aeb@\@rgii @req}{[#1]}}% + \fi + \edef\x{\noexpand + \RequirePackage{\@rgii}\@nameuse{aeb@\@rgii @req}}\x +} +\@ifpackageloaded{web}{} +{% + \@ifundefined{aeb@web@opts}{}{\ap@RP{web}}% +} +\@ifpackageloaded{exerquiz}{} +{% + \@ifundefined{aeb@exerquiz@opts}{}{\ap@RP{exerquiz}}% +} +\@ifpackageloaded{hyperref}{} +{% + \@ifundefined{aeb@hyperref@opts}{}{\ap@RP{hyperref}}% +} +\@ifpackageloaded{eq2db}{} +{% + \@ifundefined{aeb@eq2db@opts}{}{\ap@RP{eq2db}}% +} +\@ifpackageloaded{dljslib}{} +{% + \@ifundefined{aeb@dljslib@opts}{}{\ap@RP{dljslib}}% +} +\@ifpackageloaded{insdljs}{\let\execjs\aebp@YES} +{% + \ap@RP[execJS]{insdljs}[2016/07/31]% incls conv-xkv +} +\@ifpackageloaded{eforms}{\let\execjs\aebp@YES} +{% + \@ifundefined{aeb@eforms@opts}{} + {\ap@RP[execJS]{eforms}[2017/01/03]}% +} +\@ifpackageloaded{aebxmp}{\aebp@PkgWarningi{aebxmp}} +{% + \@ifundefined{aeb@aebxmp@opts}{} + {\edef\temp@exp{\ifpdfmarkup + \noexpand\ap@RP{aebxmp}\else + \if@useacrobat + \noexpand\ap@RP{aebxmp}[2016/05/12]\else + \noexpand\aebp@PkgWarningiii{aebxmp}\fi\fi}\temp@exp} +} +\@ifpackageloaded{graphicxsp}{\aebp@PkgWarningi{graphicxsp}} +{% + \@ifundefined{aeb@graphicxsp@opts}{} + {\edef\temp@exp{\ifpdfmarkup + \noexpand\ap@RP{graphicxsp}\else + \noexpand\aebp@PkgWarningii{graphicxsp}\fi}\temp@exp} +} +\@ifpackageloaded{rmannot}{\aebp@PkgWarningi{rmannot}} +{% + \@ifundefined{aeb@rmannot@opts}{} + {\edef\temp@exp{\ifpdfmarkup\noexpand\ap@RP{rmannot}\else + \noexpand\aebp@PkgWarningii{rmannot}\fi}\temp@exp} +} +\let\execjs\aebp@YES +\RequirePackage{comment} +\RequirePackage{calc} +\RequirePackage{eso-pic} +\ifpdfmarkup\else\if\aebp@uselayers1 + \excludecomment{printRollover}% + \excludecomment{rollover}% +\fi\fi +% \end{macrocode} +% The following write command is used by both the layers stuff, and the attachments routines. +% \begin{macrocode} +\def\aeb@IWVO{\immediate\write\verbatim@out} +% \end{macrocode} +% \section{Support for PDF help} +% The \DescribeMacro{\pdfHelp}\cs{pdfHelp} macro requires \textsf{eforms}. We define +% the necessary commands for PDF help, as well as some comments needed for \cs{texHelp}, +% which uses layers. +% \changes{v2.1}{2016/05/15}{Moved \string\cs{pdfHelp} from \texttt{aeblayers} to +% \texttt{package} to support non-Distiller workflows.} +% \begin{macrocode} +\newsavebox{\aebsavehelp} +\newcommand{\pdfHelpIndicator}[1]{#1\thinspace${}^{\mbox + {\footnotesize\negthinspace\ding{109}}% + \raisebox{.225ex}{\llap{\color{webblue}\tiny?\hspace{1.3ex}}}}$} +\def\pdfHelpCnt{0} +\newcommand{\pdfHelp}{\@ifstar{{\count0=\pdfHelpCnt\relax +\advance\count0by1\relax\xdef\pdfHelpCnt{\the\count0 }}% + \pdfHelpi{pdfhelp-\pdfHelpCnt}}{\pdfHelpi}} +\newcommand{\pdfHelpi}[3]{% + \let\rollormargstring\texorpdfstring + \sbox{\aebsavehelp}{\pdfHelpIndicator{#3}}% + \makebox[0pt][l]{\makespecialJS\pushButton[\S{S}\BG{}\BC{}\H{N} + \TU{#2}]{#1}{\wd\aebsavehelp}{11bp}}\usebox{\aebsavehelp}% + \let\rollormargstring\@gobbletwo +} +\newcommand\pdfPHProof[3]{\small\raggedright\texttt{#3}: #2} +\newcommand\pdfPrintHelp{\@ifstar{{\count0=\pdfHelpCnt\relax +\advance\count0by1\relax\xdef\pdfHelpCnt{\the\count0}}% + \pdfPrintHelpi{pdfhelp-\pdfHelpCnt}}{\pdfPrintHelpi}} +\newcommand\pdfPrintHelpi[3]{% + \let\rollormargstring\texorpdfstring + \ifeqforpaper + \ifeq@proofing + \pdfHelp{#1}{#2}{#3}\marginpar{\Hy@pdfstringfalse + \pdfPHProof{#1}{#2}{{\Hy@pdfstringtrue#3}}}\else + \pdfHelpIndicator{#3}\fi + \else + \pdfHelp{#1}{#2}{#3}\ifeq@proofing + \marginpar{\Hy@pdfstringfalse + \pdfPHProof{#1}{#2}{{\Hy@pdfstringtrue#3}}}\fi + \fi + \let\rollormargstring\@gobbletwo +} +% \end{macrocode} +% \begin{macrocode} +% End of package segment +%</package> +%<*aeblayers> +% \end{macrocode} +% \begin{macrocode} +% \end{macrocode} +% \section{Support for OCG} +% We place PostScript code in the document that supports OCG. +% \subsection{Initialization} +% \begin{macrocode} +\newif\ifaeb@ocOn \aeb@ocOntrue +\ifaeb@ocOn +\AtBeginDocument{% +\headerps@out{% +{/OCProcSet /ProcSet findresource} stopped not +{/initialize get exec} +{ +/BeginOC /pop load def +/EndOC {} def +/SimpleOC /pop load def +/SetOCGInitState {pop pop} bind def +/OCEndPage {} def +/SetOCGIntent {pop pop} bind def +/SetOCGUsage {pop pop} bind def +/AddASEvent {pop pop pop} bind def +} +ifelse +} +}\fi +\ifaeb@ocOn + \AtEndDocument{\literalps@out{{/OCProcSet /ProcSet findresource + /terminate get exec} stopped pop}} +\fi +% \end{macrocode} +% \subsection{Supporting commands for OCG} +% In this section we install the necessary code creating and +% navigating through PDF layers. +% \subsubsection{Document JavaScript in support of OCG} +% \begin{macrocode} +\begin{insDLJS}[getxBld]{aebocg}{AeB Pro: OCG Support} +var ocgs = this.getOCGs(); +var xBlds = new Array(); +%console.println("Reindexing ocgs and creating xBlds"); +if ( ocgs != null ) { + var l = ocgs.length; + for ( i=0; i<l; i++ ) { + if (ocgs[0].name.substring(0,3) == "xb." ) + xBlds.push(ocgs.shift()); + else ocgs.push(ocgs.shift()); + } +} +var assocxLayers = new Array(); +if ( xBlds != null ) { + for ( var i=0; i<xBlds.length; i++) + assocxLayers[xBlds[i].name]=i; +} +function getxBld (name) { + var i = assocxLayers["xb."+name]; + return ( i == undefined ) ? null : xBlds[i]; +} +function toggleHelp (name) +{ + var o = getxBld(name); + if ( o != null ) o.state = (event.name.indexOf("Enter") != -1); +} +function toggleSetThisLayer(name, bState) { + var oLayer = getxBld(name); + if ( oLayer != null ) + oLayer.state = (arguments.length > 1) ? bState : !oLayer.state; +} +function getLayerState(name) { + var oLayer = getxBld(name); + return ( oLayer != null ) ? oLayer.state : null; +} +\end{insDLJS} +% \end{macrocode} +% \subsubsection{Macros for creating rollovers} +% The following commands were taken from the \textsf{APB} +% package, and slightly modified. +% \changes{v1.3f}{2012/06/01}{Added controls for adding JS code to a +% rollover; used for starting and stopping an anime.} +% \begin{macrocode} +\newcommand{\texHelpIndicator}[1]{#1\thinspace${}^{\mbox + {\footnotesize\negthinspace\ding{109}}\raisebox{.225ex} + {\llap{\color{webblue}\tiny?\hspace{1.3ex}}}}$} +\newcommand{\addJStexHelpEnter}[1]{\def\aebp@addJStexHelpEnter{\r#1}} +\newcommand{\addJStexHelpExit}[1]{\def\aebp@addJStexHelpExit{\r#1}} +\newcommand{\resetaddJStexHelp}{% + \let\aebp@addJStexHelpEnter\@empty + \let\aebp@addJStexHelpExit\@empty +} +\resetaddJStexHelp +\newcommand{\texHelp}[2]{% + \let\rollormargstring\texorpdfstring + \sbox{\aebsavehelp}{\texHelpIndicator{#2}}% + \makebox[0pt][l]{\pushButton[\S{S}\BG{}\BC{}\H{N} + \AA{\AAMouseEnter{\JS{toggleHelp("#1");\aebp@addJStexHelpEnter}}% + \AAMouseExit{\JS{toggleHelp("#1");\aebp@addJStexHelpExit}}}]{#1}% +% \end{macrocode} +%\changes{v1.3h}{2012/11/25}{Changed height calculation in \cs{texHelp}} +% Changed height calculation in \cs{texHelp} to allow a rollover of more +% than text. +% \begin{macrocode} + {\wd\aebsavehelp}{\ht\aebsavehelp+\dp\aebsavehelp}}% + \usebox{\aebsavehelp}\resetaddJStexHelp + \let\rollormargstring\@gobbletwo +} +% \end{macrocode} +% +% \subsubsection{Macros for layers} +% We have some basic commands for creating layers in AeB Pro. +% \begin{macrocode} +\newif\ifaeb@SimpleOCOn \aeb@SimpleOCOnfalse +\newcommand{\@SOC}[2][false]{\global\aeb@SimpleOCOntrue% + \ifaeb@ocOn\literalps@out{(#2) SimpleOC (#2) #1 SetOCGInitState}\fi} +\newcommand{\b@OC}[2][false]{\ifaeb@SimpleOCOn\@aebSimpleNesterror\fi + \ifaeb@ocOn\literalps@out{(#2) BeginOC (#2) #1 SetOCGInitState}\fi} +\newcommand{\e@OC}{\ifaeb@ocOn\literalps@out{EndOC}\fi} +% \end{macrocode} +% \begin{macro}{\xBld} +% We have some basic commands for creating layers in AeB Pro. +% The syntax for \cs{xBld} is as follows: +%\begin{verbatim} +% \xBld[true|false|print=(true|false)] +% {<layer_name>}<content in layer>\eBld +%\end{verbatim} +%The description of the optional parameters follows: +%\begin{itemize} +% \item \texttt{true}\IndexKey{true}: Inserting \texttt{true} as an optional argument causes the layer to be initially visible. +% \item \texttt{false}\IndexKey{false}: Inserting \texttt{false} as an optional argument causes the layer to be initially hidden. +% The default is \texttt{false}, so if no \texttt{true} or \texttt{false} argument is passed as an optional argument, +% the layer will be initially hidden. +% \item \texttt{print}\IndexKey{print}: This key allows you to set the printability of the layer: If \texttt{print=true}, +% the layer \emph{always prints}, no matter if it is visible or not. If \texttt{print=false}, +% the layer \emph{never prints}, no matter if it is visible or not. If the print key is not specified, +% then the layer will print if visible, otherwise, it does not print. Normally, the \texttt{print} +% key is not specified, and the layer is printed if visible. +%\end{itemize} +% \begin{macrocode} +\newcommand{\xBld}[2][]{% + \setkeys{aebpxBld}{false,#1}\b@OC[\aebpxBld@visible]{xb.#2}% + \ifx\aebpxBld@print\@empty\else + \literalps@out{/Print [/Print] [(xb.#2)] AddASEvent}% + \ifAEBP@aebpxBld@print + \literalps@out{(xb.#2) << /Print<< + /PrintState/ON >> >> SetOCGUsage}% + \else + \literalps@out{(xb.#2) << /Print<< + /PrintState/OFF >> >> SetOCGUsage}% + \fi + \global\let\aebpxBld@print\@empty + \fi +} +\let\eBld\e@OC +\def\@aebSimpleNesterror{\PackageWarning{aeb} +{The scope of the last \string\Bld\space command +\MessageBreak includes the scope of the nested Bld. +\MessageBreak Executing \protect\ocOff\space to correct this. +\MessageBreak The problem occurs}\ocOff} +% \end{macrocode} +% \end{macro} +% The \textsf{keyval} definitions of the optional parameters for \cs{xBld}. +%\changes{v1.7m}{2015/08/08}{Made \texttt{print} key into a choice field} +%(2015/08/08) Made \texttt{print} key into a choice field. +% \begin{macrocode} +\newif\ifAEBP@aebpxBld@print \AEBP@aebpxBld@printfalse +\define@choicekey+{aebpxBld}{print}[\val\nr]{true,false,% + visible,always,never}[visible]{% + \ifcase\nr\relax + \def\aebpxBld@print{true}\AEBP@aebpxBld@printtrue\or + \def\aebpxBld@print{false}\AEBP@aebpxBld@printfalse\or + \let\aebpxBld@print\@empty\or + \def\aebpxBld@print{true}\AEBP@aebpxBld@printtrue\or + \def\aebpxBld@print{false}\AEBP@aebpxBld@printfalse\fi +}{\PackageWarning{aeb_pro}{Bad choice for initState, permissible values + are true, false, visible, always, and never. Try again}} +\let\aebpxBld@print\@empty +\define@key{aebpxBld}{true}[true]{\def\aebpxBld@visible{#1}} +\define@key{aebpxBld}{false}[false]{\def\aebpxBld@visible{#1}} +% \end{macrocode} +% The \texttt{initState}\IndexKey{initState} sets the initial state of the OCG, the +% default is \texttt{false}, meaning the layer is initially not shown. +% \begin{macrocode} +\define@choicekey+{aebpxBld}{initState}[\val\nr]{on,off,% + true,false}[false]{% + \ifcase\nr\relax + \def\aebpxBld@visible{true}\or + \def\aebpxBld@visible{false}\or + \def\aebpxBld@visible{true}\or + \def\aebpxBld@visible{false}\fi +}{\PackageWarning{aeb_pro}{Bad choice for initState, permissible values + are on, off, true and false. Try again}} +% \end{macrocode} +% \subsubsection{The behavior of the rollovers} +% \begin{macro}{\defineRC} +% \begin{macro}{\insertRC} +% RC stands for rollover content. \cs{defineRC} is used to define the content of the rollover +% so the content can be used for the \texttt{rollover} and the \texttt{printRollover} environments. +% These two environments are comment environments that are included or excluded depending on various +% conditions. +% +% The command \cs{csarg} is a convenience command defined in the \texttt{comment} package. +% The \texttt{comment} package is required so this command is available. +% \begin{macrocode} +\long\def\defineRC#1#2{\csarg\def{RC#1}{#2}} +\def\insertRC#1{\@nameuse{RC#1}} +\long\def\definePR#1#2{% + \ifeqforpaper\csarg\def{PR#1}{#2}\else + \ifeq@proofing\csarg\def{PR#1}{#2}\else + \csarg\let{PR#1}\relax\fi\fi +} +\def\insertPR#1{% + \ifeq@proofing\@nameuse{PR#1}\else + \csarg\let{insertPR}\@gobble\fi + \csarg\let{PR#1}\relax +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{environment}{rollover} +% \begin{environment}{printRollover} +% \begin{macro}{\definePR} +% \begin{macro}{\insertPR} +% Depending on the switches \cs{ifeqforpaper} and \cs{ifeq@proofing}, the comment environments +% \texttt{rollover} and \texttt{printRollover} are included or excluded. Also defined here are the +% two commands \cs{definePR} and \cs{insertPR} (PR stands for print rollover). These two commands +% are set equal to either \cs{defineRC} and \cs{insertRC}, or \cs{relax}, depending on the switches. +% +% If \textsf{exerquiz} is not loaded, then the switch \cs{ifeq@proofing} is undefined. We must +% define this switch in this case, and set it to \texttt{false}. +% \begin{macrocode} +\@ifundefined{ifeqforpaper}{\newif\ifeqforpaper \eqforpaperfalse}{} +\@ifundefined{ifeq@proofing}{\newif\ifeq@proofing \eq@proofingfalse}{} +\providecommand\turnProofingOn{\eq@proofingtrue} +\providecommand\turnProofingOff{\eq@proofingfalse} +% \end{macrocode} +% \DescribeMacro\proofRollovers turns on the \texttt{printRollover} environment, if there +% any defined in the document. +% \changes{v1.7}{2015/07/21}{Modified \cs{proofRollovers} command and added +% a number of other related commands.} +% \begin{macrocode} +\def\proofRollovers{% + \ifeqforpaper + \ifeq@proofing + \includecomment{rollover}% + \includecomment{printRollover}% + \else + \excludecomment{printRollover}% + \includecomment{rollover}% + \fi + \else + \ifeq@proofing + \includecomment{rollover}% + \includecomment{printRollover}% + \else + \excludecomment{printRollover}% + \includecomment{rollover}% + \fi + \fi +} +% \end{macrocode} +% We expand \cs{proofRollovers} immediately, but may be expanded in preamble with \cs{turnProofingOn}. +% \begin{macrocode} +\proofRollovers +\@onlypreamble\proofRollovers +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{environment} +% \end{environment} +% \begin{macro}{\texPrintHelp} +% The \cs{texPrintHelp} command reduces to \cs{texHelp} or typesets its second argument. +% \begin{macrocode} +\newcommand\texPHProof[2]{\small\raggedright\texttt{#1}: #2} +\let\rollormargstring\@gobbletwo +\def\texPrintHelp#1#2{% + \let\rollormargstring\texorpdfstring + \ifeqforpaper + \ifeq@proofing + \texHelp{#1}{#2}\marginpar{\Hy@pdfstringfalse + \texPHProof{#1}{#2}}\else + \texHelpIndicator{#2}\fi + \else + \texHelp{#1}{#2}\ifeq@proofing\marginpar{\Hy@pdfstringfalse + \texPHProof{#1}{#2}}\fi + \fi + \let\rollormargstring\@gobbletwo +} +% \end{macrocode} +% \end{macro} +% \subsection{In Support of Anime using Layers} +% Using layers, it is possible to create a sort of animation (anime). The following +% are some rudimentary methods for creating anime. An example can be found below, +% as well as in \texttt{aebpro\_ex4.tex}. +% +% \subsubsection{\protect\LaTeX{} Support} +% \begin{macro}{\animeBld} +% \begin{macro}{\DeclareAnime} +% The command \cs{animeBld} increments \texttt{ocSeq}, and names +% the layer so that the JS can run through the layers in an orderly way. +% +% \cs{DeclareAnime} takes three arguments, the anime base name, the speed at which +% you wish the anime to be played, and the number of frames of this animation. It +% saves these three parameters in macros, and creates \cs{animBldName}, which is used +% in the creation of the anime. See example file \texttt{aebpro\_ex4.tex}. +% \begin{macrocode} +\newcommand{\animeBld}[1][]{\stepcounter{ocSeq}% + \xBld[#1]{\animBldName}} +\newcounter{ocSeq} +% \end{macrocode} +% (10/01/01) We give an animation the special `\texttt{anime!!}' prefix, so JavaScript can identify +% animation layers. +% \begin{macrocode} +\newcommand{\animeName}[1]{anime!!#1}%01/01/2010 +\newcommand{\DeclareAnime}[3] +{% + \setcounter{ocSeq}{0}% + \xdef\animBaseName{anime!!#1}%01/01/2010 + \xdef\animSpeed{#2}\xdef\nFrames{#3}% + \gdef\animBldName{\animBaseName\#\theocSeq}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\backAnimeBtn} +% \begin{macro}{\clearAnimeBtn} +% \begin{macro}{\forwardAnimeBtn} +% The command \cs{animeBld} increments \texttt{ocSeq}, and names +% the layer so that the JS can run through the layers in an orderly way. +% +% \cs{DeclareAnime} takes three arguments, the anime base name, the speed at which +% you wish the anime to be played, and the number of frames of this animation. It +% saves these three parameters in macros, and creates \cs{animBldName}, which is used +% in the creation of the anime. See example file \texttt{aebpro\_ex4.tex}. +% \begin{itemize} +% \item \texttt{\#1}: This is an optional parameter for changing the appearance +% of the button, See the \textsf{eforms} package documentation. +% \item \texttt{\#2}: width of the button +% \item \texttt{\#3}: height of the button +% \end{itemize} +% \begin{macrocode} +\newcommand{\backAnimeBtn}[3][] +{% + \pushButton[\textFont{Wingdings3}\uCA{FEFF00C5}\TU{Reverse}#1 + \A{\JS{% + try { aebAnimeTimeOutF.running=false; } catch(e) {}\r + try { aebAnimeTimeOutB.running=false; } catch(e) {}\r + aebAnimeLayersBackward(\animSpeed,\nFrames,"\animBaseName"); + }}]{\animBaseName BtnBack}{#2}{#3}% +} +\newcommand{\clearAnimeBtn}[3][] +{% + \pushButton[\textFont{Wingdings}\CA{n}\TU{Clear}#1 + \A{\JS{% + try { aebAnimeTimeOutF.running=false; } catch(e) {}\r + try { aebAnimeTimeOutB.running=false; } catch(e) {}\r + aebAnimeLayersClear(\animSpeed,\nFrames,"\animBaseName"); + }}]{\animBaseName BtnClear}{#2}{#3}% +} +\newcommand{\forwardAnimeBtn}[3][] +{% + \pushButton[\textFont{Wingdings3}\uCA{FEFF00C6}\TU{Graph It!}#1 + \A{\JS{% + try { aebAnimeTimeOutF.running=false; } catch(e) {}\r + try { aebAnimeTimeOutB.running=false; } catch(e) {}\r + aebAnimeLayersForward(\animSpeed,\nFrames,"\animBaseName"); + }}]{\animBaseName BtnForward}{#2}{#3}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% Here is a simple example if anime, using the above commands. The code +% below uses the \textsf{pstricks-add} and \textsf{fp} packages. +%\begin{verbatim} +%\begin{center} +%\DeclareAnime{sinegraph}{10}{40} +%\def\thisframe{\animeBld\psplot[linecolor=red]{0}{\xi}{sin(x)}\eBld} +%\psset{llx=-12pt,lly=-12pt,urx=12pt,ury=12pt} +%\begin{psgraph*}[arrows=->](0,0)(-.5,-1.5)(6.5,1.5){164pt}{70pt} +% \psset{algebraic=true}% +% \rput(4,1){$y=\sin(x)$} +% \FPdiv{\myDelta}{\psPiTwo}{\nFrames}% +% \def\xi{0}% +% \multido{\i=1+1}{\nFrames}{\FPadd{\xi}{\xi}{\myDelta}\thisframe} +%\end{psgraph*} +% +%\backAnimeBtn{24bp}{12bp}\kern1bp\clearAnimeBtn{24bp}{12bp}\kern1bp +%\forwardAnimeBtn{24bp}{12bp} +%\end{center} +%\end{verbatim} +% \subsubsection{JavaScript Support} +% \begin{macrocode} +\begin{insDLJS}[_animeLayers]{animelayers} + {AeB Pro: JS in Support of Anime} +var _animeLayers = true; +var aebAnimeTimeOutF = new Object(); +aebAnimeTimeOutF.running=false; +var aebAnimeTimeOutB = new Object(); +aebAnimeTimeOutB.running=false; +var aebAnimeTimeOutC = new Object(); +function aebAnimeLayersForward(animSpeed,nFrames,baseName) +{ + var timeinterval = animSpeed; + aebAnimeTimeOutF = app.setInterval("aebAnimeTimeOutF.count++;" + + "if (aebAnimeTimeOutF.count > " + + nFrames + " || !aebAnimeTimeOutF.running )" + +" app.clearInterval(aebAnimeTimeOutF);\r" + + "else { if (aebAnimeTimeOutF.count == 1 )" + +" getxBld('"+baseName+"\#1').state=true;\t" + + "else { getxBld('"+baseName+"\#'" + + "+(aebAnimeTimeOutF.count-1)).state=false;\t" + + "getxBld('"+baseName+"\#'" + + "+aebAnimeTimeOutF.count).state=true;}}", timeinterval); + aebAnimeTimeOutF.running = true; + aebAnimeTimeOutF.start = 1; + aebAnimeTimeOutF.count=0; +} +function aebAnimeLayersBackward(animSpeed,nFrames,baseName) +{ + var timeinterval = animSpeed; + aebAnimeTimeOutB = app.setInterval("aebAnimeTimeOutB.count++;\r" + + "if (aebAnimeTimeOutB.count > "+nFrames + +"|| !aebAnimeTimeOutB.running )" + +" app.clearInterval(aebAnimeTimeOutB);\r" + + "else { if (aebAnimeTimeOutB.count == " + +nFrames+") getxBld('"+baseName+"\#1').state=false;\r" + + "else { getxBld('"+baseName+"\#'" + + "+(aebAnimeTimeOutB.start-% +aebAnimeTimeOutB.count+1)).state=false;\r" + + "getxBld('"+baseName+"\#'" + + "+(aebAnimeTimeOutB.start-% +aebAnimeTimeOutB.count)).state=true;}}", + timeinterval); + aebAnimeTimeOutB.running = true; + aebAnimeTimeOutB.start = nFrames; + aebAnimeTimeOutB.count=0; +} +function aebAnimeLayersClear(animSpeed,nFrames,baseName) +{ + aebAnimeTimeOutF.running = false; + aebAnimeTimeOutB.running = false; + clearFrames = app.setTimeOut( + "hideAllFrames("+nFrames+",\""+baseName+"\")",animSpeed); + var timeinterval = animSpeed; + aebAnimeTimeOutC = app.setInterval("aebAnimeTimeOutC.count++;\r" + + "if (aebAnimeTimeOutC.count >= "+nFrames + +") app.clearInterval(aebAnimeTimeOutC);\r" + + "else { getxBld('"+baseName+"\#'" + +"+(aebAnimeTimeOutC.start-aebAnimeTimeOutC.count)).state=false;}", + timeinterval); + aebAnimeTimeOutC.start = nFrames; + aebAnimeTimeOutC.count=0; +} +function hideAllFrames(n, baseName) +{ + for ( var i=1; i <= n ; i++ ) + getxBld(baseName+"\#"+i).state=false; +} +\end{insDLJS} +% \end{macrocode} +% \begin{macrocode} +% End of the layers segment +%</aeblayers> +%<*aebpro> +% \end{macrocode} +% +% \section{Initial View} +% Supported preferences include \texttt{HideToolbar}, \texttt{HideMenubar}, \texttt{FitWindow}, +% \texttt{Center\-Window}, \texttt{DisplayDocTitle}, +% \texttt{NonFullScreenPageMode} (\texttt{UseNone}, \texttt{UseOutlines}, \texttt{UseThumbs}, +% \texttt{UseOC}, \texttt{UseAttachments}) +% +% \subsection{Window Options} +% +% The keys recognized for the windows options are \texttt{fit}\IndexKey{fit}, +% \texttt{center}\IndexKey{center}, \texttt{fullscreen}\IndexKey{fullscreen}, +% and \texttt{showtitle}\IndexKey{showtitle}. +% \begin{macrocode} +\@tfor\aeb@windowopts:={{fit}{FitWindow}}{{center}{CenterWindow}}% + {{fullscreen}{FullScreen}}{{showtitle}{DisplayDocTitle}}\do +{% + \expandafter\getargsii\aeb@windowopts + \edef\temp@expand@def{% + \noexpand\define@key{aebWindowOpts}{\aeb@argi}[true]{% + \noexpand\def\csname aeb@windowopts\aeb@argii\endcsname{% + /\aeb@argii\space##1}% + }% + }\temp@expand@def + \csarg\let{aeb@windowopts\aeb@argii}\@empty +} +% \end{macrocode} +% \begin{macro}{\setWindowOptions} +% Set the User Window options on the Initial View tab of the Document Properties dialog box. +% \begin{macrocode} +\newcommand{\setWindowOptions}[1]{\cxkvsetkeys{aebWindowOpts}{#1}} +% \end{macrocode} +% \end{macro} +% \subsection{User Interface Options} +% Key recognized for the use interface options are \texttt{hidetoolbar}\IndexKey{hidetoolbar}, +% \texttt{hidemenubar}\IndexKey{hidemenubar}, and \texttt{hidewindowui}\IndexKey{hidewindowui}. +% \begin{macrocode} +\@tfor\aeb@uiopts:={{hidetoolbar}{HideToolbar}} + {{hidemenubar}{HideMenubar}}{{hidewindowui}{HideWindowUI}}\do{% + \expandafter\getargsii\aeb@uiopts + \edef\temp@expand@def{% + \noexpand\define@key{aebUIOpts}{\aeb@argi}[true]% + {% + \noexpand\edef\csname aeb@uiopts\aeb@argii\endcsname{% + /\aeb@argii\space##1}% + }% + }\temp@expand@def + \csarg\let{aeb@uiopts\aeb@argii}\@empty +} +% \end{macrocode} +% \begin{macro}{\setUIOptions} +% Set the User Interface options on the Initial View tab of the Document Properties dialog box. +% \begin{macrocode} +\newcommand{\setUIOptions}[1]{\cxkvsetkeys{aebUIOpts}{#1}} +% \end{macrocode} +% \end{macro} +% +% \subsection{Layout and Magnification} +% +% \subsubsection{Navigation Tab (Page Mode)} +% Supported values for the \texttt{navitab}\IndexKey{navitab} key are: +%\begin{itemize} +% \item \texttt{UseNone}: Page Only +% \item \texttt{UseOutlines}: Bookmarks Panel and Page +% \item \texttt{UseThumbs}: Pages Panel and Page +% \item \texttt{FullScreen}: Fullscreen mode +% \item \texttt{UseOC}: Layers Panel and Page +% \item \texttt{UseAttachments}: Attachments Panel and Page +%\end{itemize} +% \begin{macrocode} +\define@choicekey+{aebLayoutMag}{navitab}{UseNone,UseOutlines,% + UseThumbs,FullScreen,UseOC,UseAttachments}[UseNone]{% + \def\aeb@layoutMagNaviTab{#1}% +}{\PackageWarning{aeb}{Bad choice for PageLayout, permissible values + are UseNone, UseOutlines, UseThumbs, FullScreen,% + UseOC, UseAttachments. Try again}} +\let\aeb@layoutMagNaviTab\@empty +% \end{macrocode} +% \subsubsection{Page Layout} +% Supported value for the \texttt{pagelayout}\IndexKey{pagelayout} key are: +%\begin{itemize} +% \item \texttt{SinglePage}: Single page +% \item \texttt{OneColumn}: Single page continuous +% \item \texttt{TwoPageLeft}: Two-Up (Facing) +% \item \texttt{TwoColumnLeft}: Two-Up Continuous (Facing) +% \item \texttt{TwoPageRight}: Two-Up (Cover Page) +% \item \texttt{TwoColumnRight}: Two-Up Continuous (Cover Page) +%\end{itemize} +% \begin{macrocode} +\define@choicekey+{aebLayoutMag}{pagelayout}{SinglePage,OneColumn,% + TwoColumnLeft,TwoColumnRight,TwoPageLeft,TwoPageRight}[SinglePage]{% + \def\aeb@layoutMagPageLayout{#1}% +}{\PackageWarning{aeb}{Bad choice for PageLayout, permissible values + are SinglePage, OneColumn, TwoColumnLeft, TwoColumnRight, + TwoPageLeft,TwoPageRight. Try again}} +\let\aeb@layoutMagPageLayout\@empty +% \end{macrocode} +% \subsubsection{Magnification} +% Supported values for the \texttt{mag}\IndexKey{mag} key are: +%\begin{verbatim} +% Actual Size <</D[1 0 R/XYZ -32768 -32768 1.0]/S/GoTo>> +% Fit Page <</D[1 0 R/Fit]/S/GoTo>> +% Fit Width <</D[21 0 R/FitH -32768]/S/GoTo>> +% Fit Height <</D[1 0 R/FitV -32768]/S/GoTo>> +% Fit Visible <</D[21 0 R/FitBH -32768]/S/GoTo>> +%\end{verbatim} +% \begin{macrocode} +\define@choicekey+{aebLayoutMag}{mag}[\val\nr]% + {ActualSize,FitPage,FitWidth,FitHeight,FitVisible}[FitPage]% +{% + \ifcase\nr\relax + \edef\aeb@layoutMagMag{\dl@actualsize}\or + \def\aeb@layoutMagMag{\dl@fitpage}\or + \def\aeb@layoutMagMag{\dl@fitwidth}\or + \def\aeb@layoutMagMag{\dl@fitheight}\or + \def\aeb@layoutMagMag{\dl@fitvisible}\fi +% \end{macrocode} +%\changes{v2.2}{2016/07/26}{Change division from postscript operation to a tex calculation} +% Change division from postscript operation to a tex calculation to support the \texttt{useacrobat} option. +% \begin{macrocode} +}{\setlength\@tempdima{1pt*\ratio{\val pt}{100pt}}% + \edef\aeb@layoutMagMag{\dl@mag{\strip@pt\@tempdima}}} +\let\aeb@layoutMagMag\@empty +% \end{macrocode} +% \subsubsection{Open to page} +% The \texttt{openatpage}\IndexKey{openatpage} key takes a page number as its value. +% \begin{macrocode} +\define@key{aebLayoutMag}{openatpage}[1]{\def\aeb@openatpageChoice{#1}% + \ifpdfmarkup\def\aeb@layoutMagPage{Page#1}\else + \def\aeb@layoutMagPage{#1}\fi} +\let\aeb@openatpageChoice\@empty +\let\aeb@layoutMagPage\@empty +% \end{macrocode} +% \begin{macro}{\setLayoutMag} +% Set the Layout and Magnifications options on the Initial View tab of the Document Properties dialog box. +% \begin{macrocode} +\newcommand{\setLayoutMag}[1]{\setkeys{aebLayoutMag}{openatpage=1}% + \cxkvsetkeys{aebLayoutMag}{#1}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\DeclareInitView} +% This command is the ultimate holder of the Initial View data. It has three keys +% \texttt{layoutmag}\IndexKey{layoutmag}, +% \texttt{windowoptions}\IndexKey{windowoptions} and \texttt{uioptions}\IndexKey{uioptions}. The +% values for each of these three are key values for the commands defined above: +% \cs{setLayoutMag}, \cs{setWindowOptions} and \cs{setUIOptions}. +% \begin{macrocode} +\define@key{aebDeclareInitView}{layoutmag} + {\def\aebDeclareInitView@layoutmag{#1}} +\let\aebDeclareInitView@layoutmag\@empty +\define@key{aebDeclareInitView}{windowoptions} + {\def\aebDeclareInitView@windowoptions{#1}} +\let\aebDeclareInitView@windowoptions\@empty +\define@key{aebDeclareInitView}{uioptions} + {\def\aebDeclareInitView@uioptions{#1}} +\let\aebDeclareInitView@uioptions\@empty +\newcommand{\DeclareInitView}[1]{% + \setkeys{aebDeclareInitView}{#1}% + \edef\temp@expand@sets{% + \noexpand\setLayoutMag{\aebDeclareInitView@layoutmag}% + \noexpand\setWindowOptions{\aebDeclareInitView@windowoptions}% + \noexpand\setUIOptions{\aebDeclareInitView@uioptions}% + }\temp@expand@sets +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\taggedPDF} +% Added 07/08/09 to support tagged pdf, principally tabbing using structure. Strictly +% speaking, the document need not be marked as tagged. +% \begin{macrocode} +\providecommand{\taggedPDF}{\def\aeb@TaggedPDF{true}} +\let\aeb@TaggedPDF\@empty +\@onlypreamble\taggedPDF +% \end{macrocode} +% \end{macro} +% Additional Open action +% \begin{macro}{\additionalOpenAction} +% Document open action, this command is renamed to \cmd{\addToDocOpen} and enhanced. +% \begin{macro}{\addToDocOpen} +% \changes{v1.7}{2015/06/11}{Renamed \cmd{\additionalOpenAction} to +% \cmd{\addToDocOpen}, this version is additive.} +% This command enhances \cmd{\additionalOpenAction}. This version can be used +% several times in the preamble with possibly different action types. +% Use the command \cmd{\addToDocOpen} to include additional action to be performed when the +% document opens. This is different from the actions that may be performed when the first page +% is opened. In fact, \emph{this action is independent of what what page is initially opened}. +% \begin{macro}{\requiresVersion} +%\changes{v0.8h}{2008/07/19} +%{ +% Added an optional argument to \cs{requiresVersion}, to give the option +% of only warning the user that a certain version is required; no exiting +% of the document is forced on the user. +%} +% \cmd{\requiresVersion} can be used to put a version condition on viewing the document. \cs{requiresVersion} +% uses \cmd{\addToDocOpen}. If you want to combine several actions, including a version requirement +% you''ll have to use \cmd{\addToDocOpen}. Usage: +%\begin{verbatim} +% \requiresVersion{7} +%\end{verbatim} +% \begin{macro}{\alternateDocumentURL} +% An URL to direct the user to, it is used by \cmd{requiresVersion} when the version requirement +% is not met. +% \begin{macro}{\requiredVersionMsg} +% \cs{requireVersionMsg} is the message that is displayed when the version condition is not met. +% \begin{macro}{\requiredVersionMsgRedirect} +% An redirect message when the version requirement fails, and the document is in a browser. +% \begin{macro}{\afterRequirementPassedJS} +% A hook into the end of the \cmd{\requiresVersion} command for additional JS to be +% executed. +% \begin{macrocode} +\let\aeb@addOpenAction\@empty +\let\aeb@addActionCode\@empty +\let\aeb@addOpenActionArg\@empty +\def\AEB@psMrk{[\space} +\let\aebpopentoks\@empty +\let\aebpFA\aebp@NO +\def\aebp@rightDelimiters{} +% \end{macrocode} +% \begin{macro}{\addToDocOpen} +% The argument of \cmd{\addToDocOpen} is an action, usually +% JavaScript or named. +%\begin{verbatim} +% \addToDocOpen{/S/GoTo/D[\Page{2}/Fit]} +% \addToDocOpen{\JS{console.println("Public: Open it baby!");}} +%\end{verbatim} +% As of 2015/06/15, the original version of \cs{addToDocOpen} was moved to +% \textsf{insdljs} (v2.1). This redefinition extends that capability slightly +% by incorporating into it the \cs{dev@addToDocOpen} command, see definition +% below. +% \changes{v1.9}{2016/03/03}{Redefine \string\cs{addtoDocOpen} only for pdfmarkup} +% \par\medskip\noindent +% The \cmd{\addToDocOpen} command is the major interface +% between the document author for inserting open actions (not first page actions). +% At least in the case of \textsf{pdflatex}, \textsf{hyperref} has the potential of +% overwriting the user's choices with its own choice. We turn off the open page +% action of \textsf{hyperref} by setting the following two commands to empty. +% \begin{macrocode} +\let\@pdfstartview\@empty +\let\@pdfstartpage\@empty +% \end{macrocode} +% Now for the definition of \cmd\addToDocOpen. +% \changes{v2.1}{2016/05/15}{Finalized changes to \string\cs{addToDocOpen} for +% non-Distiller workflows.} +% \begin{macrocode} +\renewcommand{\addToDocOpen}[1]{% +% \end{macrocode} +% The \cs{aebpFA} flag indicates whether this command has been used. The first it is +% used, we set things up. +% \begin{macrocode} + \ifx\aebpFA\aebp@NO + \gdef\aeb@addOpenActionArg{#1}% + \g@addto@macro\aebpopentoks{#1}% + \def\aeb@addActionCode{\bgroup\makeJSspecials\dl@preProcDefns +\ifpdfmarkup + \literalps@out{\AEB@psMrk/_objdef {pubAddToDocOpen} + /type/dict /OBJ pdfmark^^J% + \AEB@psMrk{pubAddToDocOpen} + << \aebpopentoks + \ifx\dev@addOpenAction\@empty\else + \ifx\aeb@addOpenActionArg\@empty\else^^J% + \dev@addOpenAction\fi\fi\aebp@rightDelimiters + >> /PUT pdfmark}% + \gdef\pubAddToDocOpen{{pubAddToDocOpen}}% + \xdef\aeb@addOpenAction{/Next \pubAddToDocOpen}% +\else\ifpdf + \immediate\pdfobj{<< \aebpopentoks + \ifx\dev@addOpenAction\@empty\else + \ifx\aeb@addOpenActionArg\@empty\else^^J% + \dev@addOpenAction\fi\fi\aebp@rightDelimiters + >>}\xdef\pubAddToDocOpen{\the\pdflastobj\space 0 R}% + \xdef\aeb@addOpenAction{/Next \pubAddToDocOpen}% +\else\ifxetex + \immediate\@pdfm@mark{obj @pubAddToDocOpen << \aebpopentoks + \ifx\dev@addOpenAction\@empty\else + \ifx\aeb@addOpenActionArg\@empty\else^^J% + \dev@addOpenAction\fi\fi\aebp@rightDelimiters >> }% + \gdef\pubAddToDocOpen{@pubAddToDocOpen}% + \xdef\aeb@addOpenAction{/Next \pubAddToDocOpen}% +\fi\fi\fi\egroup}% +% \end{macrocode} +% Set the \cs{aebpFA} flag to \cs{aebp@YES} to indicate this command has been executed +% at least once. +% \begin{macrocode} + \global\let\aebpFA\aebp@YES + \else +% \end{macrocode} +% If the document author uses this command a second time, the code goes to here. +% \begin{macrocode} + \edef\aebp@dljstmp{\aebp@rightDelimiters}% + \xdef\aebp@rightDelimiters{\aebp@dljstmp >> }% + \g@addto@macro\aebpopentoks{/Next << #1 }% + \fi +} +\let\additionalOpenAction\addToDocOpen +% \end{macrocode} +% \end{macro} +% \begin{macro}{\dev@addToDocOpen} +% \changes{v1.7}{2015/06/07}{Added private additional action} +% The \cs{dev@addToDocOpen} is similar to +% \cs{addToDocOpen} but is meant for package developers. These actions are executed +% \emph{after the actions} of \cs{addToDocOpen}. +% \changes{v2.1}{2016/05/15}{Extended \string\cs{dev@addToDocOpen} to include +% non-Distiller workflows.} +% \begin{macrocode} +\let\dev@addOpenAction\@empty +\let\dev@addOpenActionArg\@empty +\let\dev@addActionCode\@empty +\let\aebpFAP\aebp@NO +\let\aebpopentoksP\@empty +\def\aebp@rightDelimitersP{} +\newcommand{\dev@addToDocOpen}[1]{% +% \end{macrocode} +% The \cs{aebpFAP} flag indicates whether this command has been used. The first it is +% used, we set things up. +% \begin{macrocode} + \ifx\aebpFAP\aebp@NO + \gdef\dev@addOpenActionArg{#1}% + \g@addto@macro\aebpopentoksP{#1}% + \def\dev@addActionCode{\bgroup\makeJSspecials\dl@preProcDefns +\ifpdfmarkup + \literalps@out{\AEB@psMrk/_objdef {privAddDocOpen} + /type/dict /OBJ pdfmark^^J% + \AEB@psMrk{privAddDocOpen} << \aebpopentoksP + \aebp@rightDelimitersP\space>> /PUT pdfmark}% + \gdef\privAddDocOpen{{privAddDocOpen}}% + \gdef\dev@addOpenAction{/Next {privAddDocOpen}}% +\else\ifpdf + \immediate\pdfobj{<< \aebpopentoksP + \aebp@rightDelimitersP\space>>}% + \xdef\privAddDocOpen{\the\pdflastobj\space 0 R}% + \xdef\dev@addOpenAction{/Next \privAddDocOpen}% +\else\ifxetex + \immediate\@pdfm@mark{obj @privAddToDocOpen << \aebpopentoksP + \aebp@rightDelimitersP\space>> }% + \gdef\privAddDocOpen{@privAddToDocOpen}% + \gdef\dev@addOpenAction{/Next \privAddDocOpen}% +\fi\fi\fi\egroup}% +% \end{macrocode} +% Set the \cs{aebpFAP} flag to \cs{aebp@YES} to indicate this command has been executed +% at least once. +% \begin{macrocode} + \global\let\aebpFAP\aebp@YES +% \end{macrocode} +% If the package developer uses this command a second time, the code goes to here. +% \begin{macrocode} + \else + \edef\aebp@dljstmpP{\aebp@rightDelimitersP}% + \xdef\aebp@rightDelimitersP{\aebp@dljstmpP >> }% + \g@addto@macro\aebpopentoksP{/Next << #1 }% + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +\def\aebp@warnonly{warnonly} +\newcommand{\aebp@app@title}{AcroTeX Message} +% \end{macrocode} +%\begin{verbatim} +% #1 = warnonly or empty +% #2 = version number +%\end{verbatim} +% \begin{macrocode} +\newcommand{\requiresVersion}[2][]{\def\aebp@argi{#1}% + \def\requiredVersionNumber{#2}\dev@addToDocOpen{\JS{% +\ifx\aebp@argi\aebp@warnonly + var warnOnly=true; +\else + var warnOnly=false; +\fi +% \end{macrocode} +% (2015/10/14) Inserted parentheses to prevent dvips from breaking lines within a string. +% \changes{v1.7n}{2015/10/14}{Inserted parentheses to prevent dvips from breaking lines within a string.} +% \begin{macrocode} + var reqVerMsgC=("\aeb@requiredVersionMsg\space") + + ((warnOnly) ? ("\aeb@reqVerMsgW") : ("\aeb@reqVerMsgC")); + var reqVerMsgR=("\aeb@requiredVersionMsgRedirect\space") + + ((warnOnly) ? ("\aeb@reqVerMsgW") : ("\aeb@reqVerMsgR")); + if( app.viewerVersion < #2 ) { + var viewerPassedReq=false; + try { + if (this.external) { + app.alert({cTitle:"\aebp@app@title", cMsg: reqVerMsgR}); + if (!warnOnly) { + if (app.viewerVersion >= 7.0) + app.launchURL("\aebAlternateDocumentURL"); + else + this.getURL("\aebAlternateDocumentURL",false); + } + } else { + app.alert({cTitle:"\aebp@app@title", cMsg: reqVerMsgC}); + if (!warnOnly) this.closeDoc(true); + } + } catch(e) {} + } else { + var viewerPassedReq=true; + \aeb@ViewerPassedRequirementJS + } +}}} +\def\requiredVersionNumber{7} +\newcommand{\alternateDocumentURL}[1]{\def\aebAlternateDocumentURL{#1}} +\alternateDocumentURL{http://www.acrotex.net/} +\newcommand{\requiredVersionMsg}[1]{\def\aeb@requiredVersionMsg{#1}} +\requiredVersionMsg{This document requires Adobe Reader or Acrobat, + version \requiredVersionNumber\space or later.} +\newcommand{\requiredVersionResult}[3]{\def\aeb@reqVerMsgC{#1}% + \def\aeb@reqVerMsgR{#2}\def\aeb@reqVerMsgW{#3}} +\requiredVersionResult{The document is now closing.} + {Redirecting browser to an alternate page.} + {Some features of this document may not work properly.} +\newcommand{\requiredVersionMsgRedirect}[1]{% + \def\aeb@requiredVersionMsgRedirect{#1}} +\requiredVersionMsgRedirect{% + This document requires Adobe Reader or Acrobat, + version \requiredVersionNumber\space or later.} +\newcommand{\afterRequirementPassedJS}[1]{% + \def\aeb@ViewerPassedRequirementJS{#1}} +\let\aeb@ViewerPassedRequirementJS\@empty +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% Now let's put it all together. The two flags, \cs{aebpFA} and \cs{aebpFAP} indicate +% whether the commands \cs{addToDocOpen} and \cs{dev@addToDocOpen} were used. +% \begin{macrocode} +\def\aeb@SetCatalog{% + \ifx\aebpFA\aebp@NO\addToDocOpen{\JS{;}}\fi + \ifx\aebpFAP\aebp@YES\dev@addActionCode\fi + \aeb@addActionCode +% \end{macrocode} +% The viewer preferences. +% \begin{macrocode} +\def\aeb@CatEntry{/ViewerPreferences<<% + \ifx\aeb@windowoptsFitWindow\@empty\else + \aeb@windowoptsFitWindow\fi + \ifx\aeb@windowoptsCenterWindow\@empty\else + \aeb@windowoptsCenterWindow\fi + \ifx\aeb@windowoptsDisplayDocTitle\@empty\else + \aeb@windowoptsDisplayDocTitle\fi + \ifx\aeb@uioptsHideToolbar\@empty\else + \aeb@uioptsHideToolbar\fi + \ifx\aeb@uioptsHideMenubar\@empty\else + \aeb@uioptsHideMenubar\fi + \ifx\aeb@uioptsHideWindowUI\@empty\else + \aeb@uioptsHideWindowUI\fi + \ifx\aeb@layoutMagNaviTab\@empty\else + /NonFullScreenPageMode/\aeb@layoutMagNaviTab\fi +>>% + \ifx\aeb@TaggedPDF\@empty\else + /MarkInfo<</Marked true>>\fi + \ifx\aeb@layoutMagPageLayout\@empty\else + /PageLayout/\aeb@layoutMagPageLayout\fi + \ifx\aeb@windowoptsFullScreen\@empty + \ifx\aeb@layoutMagNaviTab\@empty\else + /PageMode/\aeb@layoutMagNaviTab\fi + \else/PageMode/FullScreen\fi +% \end{macrocode} +% The open action key (\textsf{\textbf{OpenAction}}) is implemented any of three ways, +% depending on the driver. The command \cs{pubAddToDocOpen} is an indirect reference +% to additional open actions; this is defined in \cs{addToDocOpen}. +%\changes{v1.9}{2016/03/03}{Removing pdfmark code for non-Distiller workflow} +% \begin{macrocode} +\ifpdfmarkup + \ifx\aeb@layoutMagPage\@empty + \ifx\aeb@layoutMagMag\@empty + /OpenAction \pubAddToDocOpen + \else/OpenAction<</D[{Page1}\aeb@layoutMagMag]% + /S/GoTo\aeb@addOpenAction>>\fi + \else + \ifx\aeb@layoutMagMag\@empty + /OpenAction<</D[{\aeb@layoutMagPage}/Fit]% + /S/GoTo\aeb@addOpenAction>>\else + /OpenAction<</D[{\aeb@layoutMagPage}\aeb@layoutMagMag]% + /S/GoTo\aeb@addOpenAction>>\fi + \fi +\else\ifpdf + \ifx\aeb@layoutMagPage\@empty + \ifx\aeb@layoutMagMag\@empty + /OpenAction \pubAddToDocOpen + \else/OpenAction <<% + /D[\pdfpageref1\space\space 0 R\aeb@layoutMagMag]% + /S/GoTo\aeb@addOpenAction>>\fi + \else + \ifx\aeb@layoutMagMag\@empty + /OpenAction<</D[\expandafter + \pdfpageref\aeb@layoutMagPage\space\space 0 R/Fit]% + /S/GoTo\aeb@addOpenAction>>\else + /OpenAction<</D[\expandafter\pdfpageref + \aeb@layoutMagPage\space\space 0 R\aeb@layoutMagMag]% + /S/GoTo\aeb@addOpenAction>>\fi + \fi +\else\ifxetex + \ifx\aeb@layoutMagPage\@empty + \ifx\aeb@layoutMagMag\@empty + /OpenAction \pubAddToDocOpen + \else/OpenAction<</D[@page1 \aeb@layoutMagMag]% + /S/GoTo\aeb@addOpenAction>>\fi + \else + \ifx\aeb@layoutMagMag\@empty + /OpenAction<</D[@page\aeb@layoutMagPage\space/Fit]% + /S/GoTo\aeb@addOpenAction>>\else + /OpenAction<<% + /D[@page\aeb@layoutMagPage\space\aeb@layoutMagMag]% + /S/GoTo\aeb@addOpenAction>>\fi + \fi +\fi\fi\fi}% +% \end{macrocode} +% Load \cs{aeb@SetCatalog} only if a Distiller user. +%\changes{v1.9}{2016/03/03}{Removing pdfmark code for non-Distiller workflow} +%\changes{v2.0}{2016/05/08}{Attempt to extend package to include more features +%for pdftex and xetex. Modified \string\cs{aeb@SetCatalog}.} +% \begin{macrocode} + \ifpdfmarkup\literalps@out{\AEB@psMrk{Catalog} + <<\aeb@CatEntry>> /PUT pdfmark}\else + \ifpdf\pdfcatalog{\aeb@CatEntry}\else + \ifxetex\immediate\@pdfm@mark{put @catalog <<\aeb@CatEntry>>}% + \fi\fi\fi +} +\AtBeginDocument{\aeb@SetCatalog} +% \end{macrocode} +% +% \section{Fullscreen and Transitions} +% +% \subsection{\texorpdfstring{\cs{setDefaultFS}}{\textbackslash setDefaultFS}} +% \begin{macro}{\setDefaultFS} +% Use \cs{setDefaultFS} to set the defaults for fullscreen +% mode in the Adobe Reader or Acrobat. +% \begin{macrocode} +\newcommand{\setDefaultFS}[1] +{% + \setkeys{aebDefFS}{Trans=Replace}\setkeys{aebDefFS}{#1}% + \makeatletter + \InputIfFileExists{fsprodef.js}{}{\PackageWarning{aeb_pro} + {Cannot find fsprodef.js, please run aeb_pro.ins again}} + \makeatother +} +\@onlypreamble\setDefaultFS +% \end{macrocode} +% \end{macro} +% Definitions of the values of the \texttt{Trans}\IndexKey{Trans} key for +% supported transitions; these are set using the command +% \cs{setDefaultFS}. +% +% \begin{macrocode} +\def\aeb@NoTransition{NoTransition} +\define@choicekey+{aebDefFS}{Trans} +{NoTransition,UncoverLeft,UncoverRight,UncoverDown,UncoverUp,% +UncoverLeftDown,UncoverLeftUp,UncoverRightDown,UncoverRightUp,% +CoverLeft,CoverRight,CoverDown,CoverUp,CoverLeftDown,CoverLeftUp,% +CoverRightDown,CoverRightUp,PushLeft,PushRight,PushDown,PushUp,% +PushLeftDown,PushLeftUp,PushRightDown,PushRightUp,FlyInRight,% +FlyInLeft,FlyInDown,FlyInUp,FlyOutRight,FlyOutLeft,FlyOutDown,% +FlyOutUp,FlyIn,FlyOut,Blend,Fade,Random,Dissolve,% +GlitterRight,GlitterDown,GlitterRightDown,BoxIn,BoxOut,% +BlindsHorizontal,BlindsVertical,SplitHorizontalIn,% +SplitHorizontalOut,SplitVerticalIn,SplitVerticalOut,WipeLeft,% +WipeRight,WipeDown,WipeUp,WipeLeftDown,WipeLeftUp,% +WipeRightDown,WipeRightUp,Replace,ZoomInDown,ZoomInLeft,% +ZoomInLeftDown,ZoomInLeftUp,ZoomInRight,ZoomInRightDown,% +ZoomInRightUp,ZoomInUp,ZoomOutDown,ZoomOutLeft,ZoomOutLeftDown,% +ZoomOutLeftUp,ZoomOutRight,ZoomOutRightDown,ZoomOutRightUp,% +ZoomOutUp,CombHorizontal,CombVertical}[Replace]{% + \def\aeb@arg{#1}\ifx\aeb@arg\@empty + \let\aeb@fsTran\@empty\else + \ifx\aeb@arg\aeb@NoTransition + \def\aeb@fsTran{app.fs.defaultTransition = "";^^J} + \else + \def\aeb@fsTran{app.fs.defaultTransition = "#1";^^J}\fi\fi} +{\PackageWarning{aeb}{Bad choice, try again. Meanwhile, + will use the default, Replace}% + \def\aeb@fsTran{app.fs.defaultTransition = "Replace";^^J}} +% \end{macrocode} +% The \texttt{bgColor}\IndexKey{bgColor} key. +% \begin{macrocode} +\define@key{aebDefFS}{bgColor}[]{% + \def\aeb@arg{#1}\ifx\aeb@arg\@empty + \let\aeb@fsBGColor\@empty\else + \def\aeb@fsBGColor{app.fs.backgroundColor = #1;^^J}\fi} +\let\aeb@fsBGColor\@empty +% \end{macrocode} +% The \texttt{timeDelay}\IndexKey{timeDelay} key. +% \begin{macrocode} +\define@key{aebDefFS}{timeDelay}[]{% + \def\aeb@arg{#1}\ifx\aeb@arg\@empty + \let\aeb@fstimeDelay\@empty\else + \def\aeb@fstimeDelay{app.fs.timeDelay = #1;^^J}\fi} +\let\aeb@fstimeDelay\@empty +% \end{macrocode} +% The \texttt{loop}\IndexKey{loop} key. +% \begin{macrocode} +\define@boolkey{aebDefFS}{loop}[true]{% + \def\aeb@fsLoop{app.fs.loop = #1;^^J}} +\let\aeb@fsLoop\@empty +% \end{macrocode} +% The \texttt{cursor}\IndexKey{cursor} key. +% \begin{macrocode} +\define@choicekey+{aebDefFS}{cursor}{hidden,delay,visible}{% + \def\aeb@arg{#1}\ifx\aeb@arg\@empty + \let\aeb@fscursor\@empty\else + \def\aeb@fscursor{app.fs.cursor = cursor.#1;^^J}\fi +}{\PackageWarning{aeb}{Bad choice for cursor, permissible values + are hidden, delay and visible. Try again}} +\let\aeb@fscursor\@empty +% \end{macrocode} +% The \texttt{escape}\IndexKey{escape} key. +% \begin{macrocode} +\define@boolkey{aebDefFS}{escape}[true]{% + \def\aeb@fsEscape{app.fs.escapeExits = #1;^^J}} +\let\aeb@fsEscape\@empty +% \end{macrocode} +% The \texttt{clickAdv}\IndexKey{clickAdv} key. +% \begin{macrocode} +\define@boolkey{aebDefFS}{clickAdv}[true]{% + \def\aeb@fsclickAdv{app.fs.clickAdvances = #1;^^J}} +\let\aeb@fsclickAdv\@empty +% \end{macrocode} +% The \texttt{fullscreen}\IndexKey{fullscreen} key. +% \begin{macrocode} +\define@boolkey{aebDefFS}{fullscreen}[true]{% + \def\aeb@windowoptsFullScreen{true}% +} +\let\aeb@fsFS\@empty +% \end{macrocode} +% The \texttt{useTimer}\IndexKey{useTimer} key. +% \begin{macrocode} +\define@boolkey{aebDefFS}{useTimer}[true]{% + \def\aeb@fsuseTimer{app.fs.useTimer = #1;^^J}} +\let\aeb@fsuseTimer\@empty +% \end{macrocode} +% The \texttt{usePageTiming}\IndexKey{usePageTiming} key. +% \begin{macrocode} +\define@boolkey{aebDefFS}{usePageTiming}[true]{% + \def\aeb@fsusePageTiming{app.fs.usePageTiming = #1;^^J}} +\let\aeb@fsusePageTiming\@empty +% \end{macrocode} +% \subsection{\texorpdfstring{\cs{setPageTransition}}{\textbackslash setPageTransition}} +% +% \begin{macro}{\setPageTransition} +% By setting the \texttt{aebTrans} family of keys, you can change the transition +% effect of the next slide. +% \changes{v2.1}{2016/05/15}{Finalized changes in \string\cs{setPageTransition} for +% non-Distiller workflows.} +% \begin{macrocode} +\def\aebp@PageTransCnt{0} +\def\aebp@Step@PageTransCnt{{\count0=\aebp@PageTransCnt\relax + \advance\count0by1\relax + \xdef\aebp@PageTransCnt{\the\count0 }}} +\newcommand{\setPageTransition}[1]{% + \begingroup + \aebp@Step@PageTransCnt + \setkeys{aebTrans}{TransDur,Speed,#1}% + \edef\aeb@pagetranschoices{\aeb@Page@Dur + /Trans <<\aeb@Trans@Dur\aeb@TranChoice>>}% + \csarg{\xdef}{aeb@pagetransCodeL\aebp@PageTransCnt}{% + \ifpdfmarkup + \noexpand\literalps@out{\AEB@psMrk{ThisPage} << + \aeb@pagetranschoices\space>> /PUT pdfmark}% + \else\ifpdf +% \end{macrocode} +% There may be open / close page actions already defined, so we combine +% previous page actions with current page actions. This seems necessary +% only for \textsf{pdftex}. +% \begin{macrocode} + \noexpand\global\noexpand\pdfpageattr=\noexpand\expandafter + {\noexpand\the\noexpand\pdfpageattr\aeb@pagetranschoices}% + \else\ifxetex + \noexpand\immediate\noexpand\@pdfm@mark{put @thispage << + \aeb@pagetranschoices\space >>} + \fi\fi\fi + } + \ifx\aeb@TranChoice\@empty\else + \csarg\xdef{aebpP@geTr@nsP@ge\arabic{page}}% + {\noexpand\@nameuse{aeb@pagetransCodeL\aebp@PageTransCnt}}% + \fi + \endgroup +} +% \end{macrocode} +% \begin{macro}{\setPageTransitionAt} +% Set the transition for a particular page +% \changes{v2.1}{2016/05/15}{Finalized changes in \string\cs{setPageTransitionAt} for +% non-Distiller workflows.} +% \begin{macrocode} +\newcommand{\setPageTransitionAt}[2]{% + \begingroup + \aebp@Step@PageTransCnt + \setkeys{aebTrans}{#2}% + \edef\aeb@pagetranschoices{\aeb@Page@Dur + /Trans <<\aeb@Trans@Dur\aeb@TranChoice>>}% + \csarg{\xdef}{aeb@pagetransCode\aebp@PageTransCnt}{% + \ifpdfmarkup + \noexpand\literalps@out{\AEB@psMrk{ThisPage} << + \aeb@pagetranschoices\space>> /PUT pdfmark}% + \else\ifpdf +% \end{macrocode} +% There may be open / close page actions already defined, so we combine +% previous page actions with current page actions. This seems necessary +% only for \textsf{pdftex}. +% \begin{macrocode} + \noexpand\global\noexpand\pdfpageattr=\noexpand\expandafter + {\noexpand\the\noexpand\pdfpageattr\aeb@pagetranschoices}% + \else\ifxetex + \noexpand\immediate\noexpand\@pdfm@mark{put @thispage << + \aeb@pagetranschoices\space>>} + \fi\fi\fi + } + \ifx\aeb@TranChoice\@empty\else + \expandafter\aebp@rse\expandafter{#1}% + \edef\shakeandbake{% + \noexpand\@for\noexpand\@mypage:=\the\aeb@parsetoks}% + \shakeandbake \do {% + \csarg\xdef{aebpP@geTr@nsP@ge\@mypage}% + {\noexpand\@nameuse{aeb@pagetransCode\aebp@PageTransCnt}}% + }% + \fi + \endgroup +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% The values of the \texttt{Trans}\IndexKey{Trans} key. There are the 50 transitions effects as listed by +% \texttt{app.fs.transitions} plus one more called +% ``\texttt{NoTransition}''. The \texttt{pdfmark} code accurately +% represents each of this options. +% \begin{macrocode} +\define@choicekey+{aebTrans}{Trans} +{NoTransition,UncoverLeft,UncoverRight,UncoverDown,UncoverUp,% +UncoverLeftDown,UncoverLeftUp,UncoverRightDown,UncoverRightUp,% +CoverLeft,CoverRight,CoverDown,CoverUp,CoverLeftDown,CoverLeftUp,% +CoverRightDown,CoverRightUp,PushLeft,PushRight,PushDown,PushUp,% +PushLeftDown,PushLeftUp,PushRightDown,PushRightUp,FlyInRight,% +FlyInLeft,FlyInDown,FlyInUp,FlyOutRight,FlyOutLeft,FlyOutDown,% +FlyOutUp,FlyIn,FlyOut,Blend,Fade,Random,Dissolve,% +GlitterRight,GlitterDown,GlitterRightDown,BoxIn,BoxOut,% +BlindsHorizontal,BlindsVertical,SplitHorizontalIn,% +SplitHorizontalOut,SplitVerticalIn,SplitVerticalOut,WipeLeft,% +WipeRight,WipeDown,WipeUp,WipeLeftDown,WipeLeftUp,% +WipeRightDown,WipeRightUp,Replace,ZoomInDown,ZoomInLeft,% +ZoomInLeftDown,ZoomInLeftUp,ZoomInRight,ZoomInRightDown,% +ZoomInRightUp,ZoomInUp,ZoomOutDown,ZoomOutLeft,ZoomOutLeftDown,% +ZoomOutLeftUp,ZoomOutRight,ZoomOutRightDown,ZoomOutRightUp,% +ZoomOutUp,CombHorizontal,CombVertical}[Replace]% + {\edef\aeb@TranChoice{\csname aeb@Trans@#1\endcsname}% +}{\PackageWarning{aeb}{Bad choice, try again}} +\let\aeb@TranChoice\@empty +\define@key{aebTrans}{TransDur}[]{\def\aeb@arg{#1}\ifx\aeb@arg\@empty + \let\aeb@Trans@Dur\@empty\else\def\aeb@Trans@Dur{/D #1}\fi} +\let\aeb@Trans@Dur\@empty +% \end{macrocode} +% Length\IndexKey{Speed} of duration of transition effect: \texttt{Slow}, \texttt{Medium}, \texttt{Fast} +% \begin{macrocode} +\define@choicekey+{aebTrans}{Speed}[\val\nr]% + {Slow,Medium,Fast}[Slow]{%dps/change 02/27/07 + \ifcase\nr\relax + \let\aeb@Trans@Speed\@empty\or + \def\aeb@Trans@Speed{/D 0.666656}\or + \def\aeb@Trans@Speed{/D 0.333328}\fi +}{\PackageWarning{aeb}{Bad choice for Speed, permissible values + are Slow, Medium and Fast. Try again}} +\let\apb@apbTrans@Speed\@empty +% \end{macrocode} +% The page duration\IndexKey{PageDur} key +% \begin{macrocode} +\define@key{aebTrans}{PageDur}[]{\def\aeb@arg{#1}\ifx\aeb@arg\@empty + \let\aeb@Page@Dur\@empty\else\def\aeb@Page@Dur{/Dur #1}\fi} +% \end{macrocode} +% The code for the values of the \texttt{Trans} key +% \begin{macrocode} +\let\aeb@Page@Dur\@empty +\def\aeb@Trans@NoTransition{} +\def\aeb@Trans@SplitHorizontalIn{/Dm/H/M/I/S/Split} +\def\aeb@Trans@SplitHorizontalOut{/Dm/H/M/O/S/Split} +\def\aeb@Trans@SplitVerticalIn{/Dm/V/M/I/S/Split} +\def\aeb@Trans@SplitVerticalOut{/Dm/V/M/O/S/Split} +\def\aeb@Trans@BlindsHorizontal{/Dm/H/S/Blinds} +\def\aeb@Trans@BlindsVertical{/Dm/V/S/Blinds} +\def\aeb@Trans@BoxIn{/M/I/S/Box} +\def\aeb@Trans@BoxOut{/M/O/S/Box} +\def\aeb@Trans@WipeLeft{/Di 180/S/Wipe} +\def\aeb@Trans@WipeRight{/Di 0/S/Wipe} +\def\aeb@Trans@WipeDown{/Di 270/S/Wipe} +\def\aeb@Trans@WipeUp{/Di 90/S/Wipe} +\def\aeb@Trans@Dissolve{/S/Dissolve} +\def\aeb@Trans@GlitterRight{/Di 0/S/Glitter} +\def\aeb@Trans@GlitterDown{/Di 270/S/Glitter} +\def\aeb@Trans@GlitterRightDown{/Di 315/S/Glitter} +\def\aeb@Trans@Replace{/S/R} +\def\aeb@Trans@FlyInRight{/Di 0/M/I/S/Fly} +\def\aeb@Trans@FlyInLeft{/Di 180/M/I/S/Fly} +\def\aeb@Trans@FlyInDown{/Di 270/M/I/S/Fly} +\def\aeb@Trans@FlyInUp{/Di 90/M/I/S/Fly} +\def\aeb@Trans@FlyOutRight{/Di 0/M/O/S/Fly} +\def\aeb@Trans@FlyOutLeft{/Di 180/M/O/S/Fly} +\def\aeb@Trans@FlyOutDown{/Di 270/M/O/S/Fly} +\def\aeb@Trans@FlyOutUp{/Di 90/M/O/S/Fly} +\def\aeb@Trans@FlyIn{/M/I/S/Fly} +\def\aeb@Trans@FlyOut{/M/O/S/Fly} +\def\aeb@Trans@PushLeft{/Di 180/S/Push} +\def\aeb@Trans@PushRight{/Di 0/S/Push} +\def\aeb@Trans@PushDown{/Di 270/S/Push} +\def\aeb@Trans@PushUp{/Di 90/S/Push} +\def\aeb@Trans@CoverLeft{/Di 180/S/Cover} +\def\aeb@Trans@CoverRight{/Di 0/S/Cover} +\def\aeb@Trans@CoverDown{/Di 270/S/Cover} +\def\aeb@Trans@CoverUp{/Di 90/S/Cover} +\def\aeb@Trans@CoverLeftDown{/Di 225.0/S/Cover} +\def\aeb@Trans@CoverLeftUp{/Di 135.0/S/Cover} +\def\aeb@Trans@CoverRightDown{/Di 315.0/S/Cover} +\def\aeb@Trans@CoverRightUp{/Di 45.0/S/Cover} +\def\aeb@Trans@UncoverLeft{/Di 180/S/Uncover} +\def\aeb@Trans@UncoverRight{/Di 0/S/Uncover} +\def\aeb@Trans@UncoverDown{/Di 270/S/Uncover} +\def\aeb@Trans@UncoverUp{/Di 90/S/Uncover} +\def\aeb@Trans@UncoverLeftDown{/Di 225.0/S/Uncover} +\def\aeb@Trans@UncoverLeftUp{/Di 135.0/S/Uncover} +\def\aeb@Trans@UncoverRightDown{/Di 315.0/S/Uncover} +\def\aeb@Trans@UncoverRightUp{/Di 45.0/S/Uncover} +\def\aeb@Trans@Fade{/S/Fade} +\def\aeb@Trans@Random{/S/Random} +\def\aeb@Trans@Blend{/S/Blend} +% \end{macrocode} +% New Transitions for Acrobat 8.0 +% \begin{macrocode} +\def\aeb@Trans@PushLeftDown{% + /S/Push/Directional/BiDir/Di 225.0/Curve/Easy} +\def\aeb@Trans@PushLeftUp{% + /S/Push/Directional/BiDir/Di 135.0/Curve/Easy} +\def\aeb@Trans@PushRightDown{% + /S/Push/Directional/BiDir/Di 315.0/Curve/Easy} +\def\aeb@Trans@PushRightUp{% + /S/Push/Directional/BiDir/Di 45.0/Curve/Easy} +\def\aeb@Trans@WipeLeftDown{% + /S/Wipe/Directional/BiDir/Di 225/Curve/Easy} +\def\aeb@Trans@WipeLeftUp{% + /S/Wipe/Directional/BiDir/Di 135/Curve/Easy} +\def\aeb@Trans@WipeRightDown% + {/S/Wipe/Directional/BiDir/Di 315/Curve/Easy} +\def\aeb@Trans@WipeRightUp{% + /S/Wipe/Directional/BiDir/Di 45/Curve/Easy} +\def\aeb@Trans@ZoomInDown{% + /S/ZoomIn/Directional/BiDir/Di 270.0/Curve/Easy} +\def\aeb@Trans@ZoomInLeft{% + /S/ZoomIn/Directional/BiDir/Di 180.0/Curve/Easy} +\def\aeb@Trans@ZoomInLeftDown{% + /S/ZoomIn/Directional/BiDir/Di 225.0/Curve/Easy} +\def\aeb@Trans@ZoomInLeftUp{% + /S/ZoomIn/Directional/BiDir/Di 135.0/Curve/Easy} +\def\aeb@Trans@ZoomInRight{% + /S/ZoomIn/Directional/BiDir/Di 0.0/Curve/Easy} +\def\aeb@Trans@ZoomInRightDown{% + /S/ZoomIn/Directional/BiDir/Di 315.0/Curve/Easy} +\def\aeb@Trans@ZoomInRightUp{% + /S/ZoomIn/Directional/BiDir/Di 45.0/Curve/Easy} +\def\aeb@Trans@ZoomInUp{% + /S/ZoomIn/Directional/BiDir/Di 90.0/Curve/Easy} +\def\aeb@Trans@ZoomOutDown{% + /S/ZoomOut/Directional/BiDir/Di 270.0/Curve/Easy} +\def\aeb@Trans@ZoomOutLeft{% + /S/ZoomOut/Directional/BiDir/Di 180.0/Curve/Easy} +\def\aeb@Trans@ZoomOutLeftDown{% + /S/ZoomOut/Directional/BiDir/Di 225.0/Curve/Easy} +\def\aeb@Trans@ZoomOutLeftUp{% + /S/ZoomOut/Directional/BiDir/Di 135.0/Curve/Easy} +\def\aeb@Trans@ZoomOutRight{% + /S/ZoomOut/Directional/BiDir/Di 0.0/Curve/Easy} +\def\aeb@Trans@ZoomOutRightDown{% + /S/ZoomOut/Directional/BiDir/Di 315.0/Curve/Easy} +\def\aeb@Trans@ZoomOutRightUp{% + /S/ZoomOut/Directional/BiDir/Di 45.0/Curve/Easy} +\def\aeb@Trans@ZoomOutUp{% + /S/ZoomOut/Directional/BiDir/Di 90.0/Curve/Easy} +\def\aeb@Trans@CombHorizontal{% + /S/Comb/Directional/BiDir/Dm/H/Curve/Easy} +\def\aeb@Trans@CombVertical{% + /S/Comb/Directional/BiDir/Dm/V/Curve/Easy} +% \end{macrocode} +% \begin{macrocode} +% End of aebpro segment +%</aebpro> +%<*fsdefjs> +% \end{macrocode} +% \subsection{JS for Fullscreen Support} +% The ``Presentation Defaults'' are used in conjunction with the +% \cs{setDefaultFS} for setting the defaults of the application. These +% settings can be viewed under the \texttt{Edit > Preferences > +% General > Full Screen}. This script save the viewers preferences, +% sets them according the needs of the document author, and upon +% closing the document, resets the original preferences. The last task +% is performed by the \texttt{willClose} environment. +% \begin{macrocode} +\begin{insDLJS}[_fsDefaults]{fsdef}{AeB Pro: Presentation Defaults} +var _fsDefaults = true; +%if ( typeof global.fsexec == "undefined" ) +if ( typeof fsexec == "undefined" ) +{ + try { + var fsexec = true; +% global.fsexec = true; + var aebdefaultTransition = app.fs.defaultTransition; + var aebbackgroundColor = app.fs.backgroundColor; + var aebloop = app.fs.loop; + var aebtimeDelay = app.fs.timeDelay; + var aebuseTimer = app.fs.useTimer + var aebusePageTiming = app.fs.usePageTiming; + var aebclickAdvances = app.fs.clickAdvances; + var aebcursor = app.fs.cursor; + var aebescapeExits = app.fs.escapeExits; +\aeb@fsTran% +\aeb@fsBGColor% +\aeb@fsLoop% +\aeb@fsclickAdv% +\aeb@fscursor% +\aeb@fstimeDelay% +\aeb@fsuseTimer% +\aeb@fsusePageTiming% +\aeb@fsEscape% +\aeb@fsFS% + } catch(e) {} +} +\end{insDLJS} +% \end{macrocode} +% This is a series of script lines that will be inserted into the \texttt{willClose} +% section of the document. These will attempt to restore the user's full screen +% defaults. +% \begin{macrocode} +\begin{fs@willClose} +try { + delete global.fsexec; + app.fs.defaultTransition = aebdefaultTransition; + app.fs.backgroundColor = aebbackgroundColor; + app.fs.loop = aebloop; + app.fs.timeDelay = aebtimeDelay; + app.fs.useTimer = aebuseTimer; + app.fs.usePageTiming = aebusePageTiming; + app.fs.clickAdvances = aebclickAdvances; + app.fs.cursor = aebcursor; + app.fs.escapeExits = aebescapeExits; +} catch(e) { console.println("Could not reset one of the defaults"); } +\end{fs@willClose} +% \end{macrocode} +% \begin{macrocode} +% End of fsdefjs segment +%</fsdefjs> +%<*aebpro> +% \end{macrocode} +% \section{Set Page Actions} +% \begin{environment}{addJSToPageOpen} +% \begin{environment}{addJSToPageOpenAt} +% \begin{environment}{addJSToPageClose} +% \begin{environment}{addJSToPageCloseAt} +% The document author can add to the default page open action through +% this environment. Use this environment between slides, effective +% the next slide. The first slide (possibly generated by +% \cs{maketitle}) is a special case: When setting the open and close +% page actions for the first page, these environments \emph{must go} +% in the preamble. +% \begin{macrocode} +\def\canceleveryPageOpen{\global\@everyPageOpenfalse + \global\let\every@PageOpen\@empty} +\def\canceleveryPageClose{\global\@everyPageClosefalse + \global\let\every@PageClose\@empty} +\newenvironment{everyPageOpen}[1][] +{\global\@everyPageOpentrue\@defineJS[#1]{\every@PageOpen}} +{\end@defineJS + \ifnum\value{page}=1\relax + \gdef\ap@AddtoOpenJS{\thisPageAction{\JS{\every@PageOpen}}{}}% + \expandafter\aftergroup\expandafter\ap@AddtoOpenJS\fi +} +\newenvironment{everyPageClose}[1][] +{\global\@everyPageClosetrue\@defineJS[#1]{\every@PageClose}} +{\end@defineJS + \ifnum\value{page}=1\relax + \gdef\ap@AddtoCloseJS{\thisPageAction{}{\JS{\every@PageClose}}}% + \expandafter\aftergroup\expandafter\ap@AddtoCloseJS\fi +} +\let\every@PageOpen\@empty +\let\every@PageClose\@empty +\newenvironment{addJSToPageOpen}[1][] +{\@defineJS[#1]{\addJST@PageOpen}}{\end@defineJS + \ifnum\value{page}=1\relax + \gdef\ap@AddtoOpenJS{\thisPageAction{\JS{\addJST@PageOpen}}{}}% + \expandafter\aftergroup\expandafter\ap@AddtoOpenJS\fi +} +\newenvironment{addJSToPageOpenAt}[2][] +{\@@defineJS[#1]{addJST@PageOpenAt}{#2}}{\end@@defineJS +% \end{macrocode} +%\changes{v1.7}{2015/06/17}{\texttt{addJSToPageOpenAt} can now be used in preamble} +% The \texttt{addJSToPageOpenAt} and \texttt{addJSToPageCloseAt} can now be used +% in the preamble on the first page. +% \begin{macrocode} + \ifnum\value{page}=1\relax\if\frstPageSpec\aebp@YES + \thisPageAction{\JS{\@nameuse{addJST@PageOpenAt1}}}{}\fi\fi +} +\newenvironment{addJSToPageClose}[1][] +{\@defineJS[#1]{\addJST@PageClose}}{\end@defineJS + \ifnum\value{page}=1\relax + \gdef\ap@AddtoCloseJS{% + \thisPageAction{}{\JS{\addJST@PageClose}}}% + \expandafter\aftergroup\expandafter\ap@AddtoCloseJS\fi +} +\newenvironment{addJSToPageCloseAt}[2][] +{\@@defineJS[#1]{addJST@PageCloseAt}{#2}}{\end@@defineJS + \ifnum\value{page}=1\relax\if\frstPageSpec\aebp@YES + \thisPageAction{}{\JS{\@nameuse{addJST@PageCloseAt1}}}\fi\fi +} +\let\addJST@PageOpen\@empty +\let\addJST@PageClose\@empty +% \end{macrocode} +% \end{environment} +% \end{environment} +% \end{environment} +% \end{environment} +% \begin{macro}{\aebp@PageOpenCloseHandler} +% This command gets expanded by \cs{AddToShipoutPicture} for each page. Here we +% define how our page actions are to be inserted. +% \begin{macrocode} +\def\aebp@PageOpenCloseHandler{% + \@ifundefined{addJST@PageOpenAt\arabic{page}}% + {\global\let\thisOpenPageActionAt\@empty}% + {\gdef\thisOpenPageActionAt{% + \@nameuse{addJST@PageOpenAt\arabic{page}}}}% + \@ifundefined{addJST@PageCloseAt\arabic{page}}% + {\global\let\thisClosePageActionAt\@empty}% + {\gdef\thisClosePageActionAt{% + \@nameuse{addJST@PageCloseAt\arabic{page}}}}% + \aebPageAction{\thisOpenPageActionAt\addJST@PageOpen}% + {\thisClosePageActionAt\addJST@PageClose}% + \global\let\addJST@PageOpen\@empty + \global\let\addJST@PageClose\@empty +} +% \end{macrocode} +% (2016/05/15) Added \cs{aebp@PageTransHandler} to handle the page +% transitions. +% \changes{v2.1}{2016/05/15}{Added the command \string\cs{aebp@PageTransHandler} to handle the page +% transitions} +% \begin{macrocode} +\def\aebp@PageTransHandler{\@ifundefined{aebpP@geTr@nsP@ge\arabic{page}} + {}{\@nameuse{aebpP@geTr@nsP@ge\arabic{page}}}} +% \end{macrocode} +% The two handlers are executed on each page +% \changes{v2.1}{2016/05/15}{Added the command \string\cs{aebp@PageTransHandler} +% to the shipout cmd \string\cs{AddToShipoutPicture}.} +% \begin{macrocode} +\AddToShipoutPicture{\aebp@PageOpenCloseHandler + \aebp@PageTransHandler} +% \end{macrocode} +% \end{macro} +% \DescribeMacro{\@@defineJS} is a variation of \cs{@defineJS}, as defined in the \textsf{insdljs} package. +% This version, at the end of the environment, calls the \cs{aebp@rse} command to parse the +% complex command argument, then makes a series of definitions to be used in the open/close +% page events. +% \begin{macrocode} +\newenvironment{@@defineJS}[3][] +{% + \gdef\argType{#2}\gdef\defineJSArg{#3}\JStoks={}% + \def\verbatim@processline + {% + \xdef\JS@temp{\the\JStoks\the\verbatim@line\defineJSjsR}% + \global\JStoks=\expandafter{\JS@temp}% + }% + \let\do\@makeother\dospecials\catcode`\^^M\active + #1% + \verbatim@start +}{% + \expandafter\aebp@rse\expandafter{\defineJSArg}% + \edef\shakeandbake{% + \noexpand\@for\noexpand\@mytoks:=\the\aeb@parsetoks}% + \aeb@parsecnt=0 \shakeandbake \do {% + \ifnum\aeb@parsecnt=0 + \edef\firsttok{\@mytoks}% + \csarg\xdef{\argType\@mytoks}{\the\JStoks}% + \else + \edef\letsmakelet{\global\let\expandafter\noexpand + \csname\argType\@mytoks\endcsname=\expandafter\noexpand + \csname\argType\firsttok\endcsname}% + \letsmakelet + \fi + \advance\aeb@parsecnt1\relax + }% +} +% \end{macrocode} +% \begin{macrocode} +\newif\ifaeb@PageOpen +\newif\ifaeb@PageClose +\newif\if@everyPageOpen\@everyPageOpenfalse +\newif\if@everyPageClose\@everyPageClosefalse +% \end{macrocode} +% \begin{macro}{\aebPageAction} +% This is used internally, but can be used by the document author. The commands creates the code +% to set an open page and a close page action. The first (optional) argument is a the page number (base 1), +% this optional argument defaults to the current page if no page number is given. The second and third +% arguments are the open and closed JavaScript actions. +% +% If the document author uses this command, he may overwrite actions created by the \texttt{addJSTo...} +% environments. See \cs{aeb@addToPageOpenCloseActions} for usage by this package. +% \changes{v2.1}{2016/05/15}{Final changes to \string\cs{aebPageAction} to include non-Distiller +% workflows.} +% \begin{macrocode} +\newcommand\aebPageAction[3][ThisPage]{% + \let\ispageactions=0\aeb@PageOpenfalse\aeb@PageClosefalse + \def\@aebOpen{#2}% + \if1\@aebOpen1% + \if@everyPageOpen + \aeb@PageOpentrue\let\ispageactions=1% + \def\@aebOpen{/O << \JS{\every@PageOpen#2} >>}% + \fi + \else + \let\ispageactions=1% + \aeb@PageOpentrue + \def\@aebOpen{/O << \JS{\every@PageOpen#2} >>}% + \fi + \def\@aebClose{#3}% + \if1\@aebClose1% + \if@everyPageClose + \aeb@PageClosetrue\let\ispageactions=1% + \def\@aebClose{/C << \JS{\every@PageClose#3} >>}% + \fi + \else + \let\ispageactions=1% + \aeb@PageClosetrue + \def\@aebClose{/C << \JS{\every@PageClose#3} >>}% + \fi + \if@everyPageOpen\aeb@PageOpentrue\let\ispageactions=1\fi + \if@everyPageClose\@everyPageClosetrue\let\ispageactions=1\fi + \if\ispageactions1% + \xdef\aebp@PageActionCode{/AA << + \ifaeb@PageOpen\@aebOpen\space\fi + \ifaeb@PageClose\@aebClose\space\fi >>} +% \end{macrocode} +% For page 1, the open page is handled by \textsf{insdljs} +% \changes{v2.0a}{2016/05/11}{Let \string\textsf{insdljs} handle page open +% for page 1.} +% \begin{macrocode} + \ifnum\value{page}=1\relax\else + \ifpdfmarkup\literalps@out{\AEB@psMrk{#1} << + \aebp@PageActionCode\space >> /PUT pdfmark}\else + \ifpdf\global\pdfpageattr=\expandafter + {\aebp@PageActionCode}\else + \ifxetex\@pdfm@mark{put @thispage << + \aebp@PageActionCode\space>>}\fi\fi\fi + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\atPage} +% \cs{atPage} is a modification of \cs{pageref}, so its value will always be an integer. +% returned in the token register \cs{aeb@parsetoks}. Used in the arguments of such environments +% as \texttt{addJSToPageOpenAt} and \texttt{addJSToPageCloseAt}. +% \begin{macrocode} +\def\aeb@exiii{\expandafter\expandafter\expandafter} +\let\ahrefexafter\aeb@exiii +\def\atPage#1{\@ifundefined{r@#1}{1} + {\aeb@exiii\@secondoffive\csname r@#1\endcsname}} +\def\labelRef#1{\@ifundefined{r@#1}{Doc-Start} + {\aeb@exiii\@fourthoffive\csname r@#1\endcsname}} +% \end{macrocode} +% \end{macro} +% The command \cs{aebp@rse} parses such arguments as +%\begin{verbatim} +% {1,3,4-6,8-12,15,\atPage{firstlabel}-\atPage{secondlabel},30-} +%\end{verbatim} +% The expanded list is returned in the token register \cs{aeb@parsetoks}. +% \begin{macrocode} +\newtoks\aeb@parsetoks +\newcount\aeb@parsecnt +\def\ap@gobtonil#1\@nil{} +\def\ap@gettonil#1\@nil{\def\to@nilarg{#1}} +\def\ap@ifspc{\ifx\@let@token\@sptoken + \let\ap@next\ap@xifspc\else + \let\ap@next\ap@gettonil\fi\ap@next} +\begingroup +\def\:{\ap@xifspc} +\expandafter\gdef\: {\futurelet\@let@token\ap@ifspc} +\endgroup +% \end{macrocode} +% \cmd{\ap@strpspcs} strips any spaces, usage: \verb~\expandafter\ap@strpspcs\cmd\@nil~ +% where \cs{cmd} is a command that expands to text; the text is returned in \cs{to@nilarg} +% without any leading spaces. +% \begin{macrocode} +\def\ap@strpspcs{\futurelet\@let@token\ap@ifspc} +\def\ap@pgrngLabelsInPream{\@ifundefined{aebLastPage} + {\PackageWarning{aeb_pro}{The \string\atPage\space + command is not supported\MessageBreak in the preamble}}{}} +\def\aeb@removelastcomma#1,\@nil{\aeb@parsetoks={#1}} +\def\aebp@rse#1{\global\let\frstPageSpec\aebp@NO + \aeb@parsetoks={}\aeb@parse#1,\relax} +\def\aeb@parse{\@ifnextchar\relax + {\expandafter\aeb@removelastcomma\the\aeb@parsetoks\@nil} + {\aeb@@parse}} +\def\aeb@@parse#1,{\aeb@@@parse#1-\@nil} +\def\aeb@@@parse#1-#2\@nil{% + \def\argi{#2}\ifx\argi\@empty\def\aeb@next{\aeb@@@@parse{#1}}\else + \def\aeb@next{\aeb@@@@@parse#1-#2}\fi\aeb@next} +\def\aeb@@@@parse#1{%single page #1 + \@ifnextchar\atPage{\ap@pgrngLabelsInPream\ap@gobtonil} + {\ap@gobtonil}#1\@nil + \aeb@parsecnt=#1\relax + \edef\edefaeb@parsetoks{\the\aeb@parsetoks\the\aeb@parsecnt,}% + \aeb@parsetoks=\expandafter{\edefaeb@parsetoks}% +% \end{macrocode} +%\changes{v1.7}{2015/06/17}{Use \cs{frstPageSpec}} +% The \cs{frstPageSpec} signals that page 1 is specified in the +% page specification argument. +% \begin{macrocode} + \ifnum\aeb@parsecnt=1\relax\global\let\frstPageSpec\aebp@YES\fi + \aeb@parse} +\def\aeb@@@@@parse#1-#2-{\def\aeb@lowerlimit{#1}\def\aeb@upperlimit{#2}% + % range argument from #1 to \csname aebLastPage\endcsname + \ifx\aeb@upperlimit\@empty + \@ifundefined{aebLastPage}{\aeb@parsecnt=#1} + {\expandafter\aeb@parsecnt\expandafter= + \csname aebLastPage\endcsname}% + \else % page range #1 to #2, switch the two if #2 < #1 + \aeb@parsecnt=\aeb@lowerlimit\relax + \edef\aeb@lowerlimit{\the\aeb@parsecnt} + \aeb@parsecnt=\aeb@upperlimit\relax + \ifnum\aeb@parsecnt<\aeb@lowerlimit\relax + \aeb@parsecnt=\aeb@lowerlimit\relax + \def\aeb@lowerlimit{#2}% + \def\aeb@upperlimit{#1}% + \fi + \fi + \@ifnextchar\atPage{\ap@pgrngLabelsInPream\ap@gobtonil} + {\ap@gobtonil}#1\@nil + \@ifnextchar\atPage{\ap@pgrngLabelsInPream\ap@gobtonil} + {\ap@gobtonil}#2\@nil + \advance\aeb@parsecnt1\relax + \edef\aeb@upperlimit{\the\aeb@parsecnt}% + \aeb@parsecnt=\aeb@lowerlimit\relax +% \end{macrocode} +%\changes{v1.7}{2015/06/17}{Use \cs{frstPageSpec}} +% If page 1 is there, is will be as the lower limit. +% The \cs{frstPageSpec} signals that page 1 is specified in the +% page specification argument. +% \begin{macrocode} + \ifnum\aeb@parsecnt=1\relax\global\let\frstPageSpec\aebp@YES\fi + \loop + \edef\edefaeb@parsetoks{\the\aeb@parsetoks\the\aeb@parsecnt,}% + \aeb@parsetoks=\expandafter{\edefaeb@parsetoks}% + \advance\aeb@parsecnt1\relax + \ifnum\aeb@parsecnt < \aeb@upperlimit\relax\repeat + \aeb@parse} +% \end{macrocode} +% \section{Set Document Actions} +% +% \begin{environment}{willClose} +% \begin{environment}{willSave} +% \begin{environment}{didSave} +% \begin{environment}{willPrint} +% \begin{environment}{didPrint} +% We add a \texttt{willClose} environment, not really meant for the document +% author to use. This environment is used with \cs{setDefaultFS} for saving +% setting and restoring the application preferences for full screen. +% \begin{macrocode} +\@ifpackageloaded{insdljs}{% + \newenvironment{fs@willClose} + {\@defineJS{\fs@will@Close}} + {\end@defineJS} + \let\fs@will@Close\@empty +}{% + \newenvironment{willClose} + {\@defineJS{\will@Close}} + {\end@defineJS} + \let\will@Close\@empty + \newenvironment{fs@willClose} + {\@defineJS{\fs@will@Close}} + {\end@defineJS} + \let\fs@will@Close\@empty + \newenvironment{willSave} + {\@defineJS{\will@Save}} + {\end@defineJS} + \let\will@Save\@empty + \newenvironment{didSave} + {\@defineJS{\did@Save}} + {\end@defineJS} + \let\did@Save\@empty + \newenvironment{willPrint} + {\@defineJS{\will@Print}} + {\end@defineJS} + \let\will@Print\@empty + \newenvironment{didPrint} + {\@defineJS{\did@Print}} + {\end@defineJS} + \let\did@Print\@empty +} +% \end{macrocode} +% \end{environment} +% \end{environment} +% \end{environment} +% \end{environment} +% \end{environment} +% In addition to the provided environments, there are developer hooks, the package developer +% can use to insert page actions, in addition to what the package user may do. +% Now put the \texttt{willClose} JS into the document \texttt{Catalog}. The developer's +% actions will possibly overwrite that of the user; under the theory that the developer's +% actions are critical to the functioning of the package. The hooks are +% \begin{macrocode} +\let\developer@will@Close\@empty +\let\developer@will@Save\@empty +\let\developer@did@Save\@empty +\let\developer@will@Print\@empty +\let\developer@did@Print\@empty +% \end{macrocode} +%\changes{v0.8g}{2008/06/30} +%{ +% Added developer hooks to this open page events. +%} +%\changes{v2.1}{2016/05/15}{Changes to \string\cs{@setDocAction} for non-Distiller workflows.} +% (2016/05/15) modify to include non-Distiller workflows. +% \begin{macrocode} +\newcommand\@setDocActions{% + \edef\test@will@Close{% + \fs@will@Close\will@Close\developer@will@Close}% + \edef\test@will@Save{\will@Save\developer@will@Save}% + \edef\test@did@Save{\did@Save\developer@did@Save}% + \edef\test@will@Print{\will@Print\developer@will@Print}% + \edef\test@did@Print{\did@Print\developer@did@Print}% + \def\aebp@DocActionsCode{/AA << % + \ifx\test@will@Close\@empty\else/WC << + \JS{\fs@will@Close\will@Close\developer@will@Close} >>\fi + \ifx\test@will@Save\@empty\else/WS << + \JS{\will@Save\developer@will@Save} >>\fi + \ifx\test@did@Save\@empty\else/DS << + \JS{\did@Save\developer@did@Save} >>\fi + \ifx\test@will@Print\@empty\else/WP << + \JS{\will@Print\developer@will@Print} >>\fi + \ifx\test@did@Print\@empty\else/DP << + \JS{\did@Print\developer@did@Print} >>\fi + >> + } + \ifpdfmarkup\literalps@out{\AEB@psMrk{Catalog} + << \aebp@DocActionsCode\space>> /PUT pdfmark}\else + \ifpdf\pdfcatalog{\aebp@DocActionsCode}\else + \ifxetex\immediate + \@pdfm@mark{put @catalog <<\aebp@DocActionsCode\space>>}\fi + \fi\fi +} +\AtBeginDocument{\@setDocActions} +% \end{macrocode} +% +% \section{In support of attachments} +% +% \subsection{Processing the \texttt{attachsource} and \texttt{attachments} key} +% +% If the value of either the \texttt{\texttt{attachsource}} or +% \texttt{attachments} keys are non empty, the values are contained +% in the macros \cs{aeb@attachsource} and \cs{aeb@attachments}. If +% either of these text macros is different from \cs{empty}, we need +% to write out a cut file that lists the requested attachments, then +% input the cut file back in at the end of the package. +% \begin{macro}{\aref} +% This command, whose argument is \textit{delimited by parentheses}, +% is to be used with \cs{inputDataObject}, defined below, to expand +% the value of the \texttt{cName} key, when the label is defined by +% \cs{labelName}. It is also used by this package to set the +% description of the attachment. +% \begin{macrocode} +\def\aref(#1){\csname aeb@aDescript@#1\endcsname} +% \end{macrocode} +% \end{macro} +% The next command \cs{aeb@initAttachWrite} we prepare to write by opening a stream, and +% starting the \texttt{execJS} environment, but only if we have an attachment request. +% \begin{macrocode} +\def\aeb@initAttachWrite{% + \newwrite \aeb@attachmentswrite + \immediate\openout \aeb@attachmentswrite \jobname_attach.cut + \let\verbatim@out\aeb@attachmentswrite + \aeb@IWVO{\string\begin{execJS}{aebpro_attach}}% + {\lccode`P=`\{\lowercase{\aeb@IWVO{try P}}}% +} +% \end{macrocode} +% \changes{v1.4}{2013/02/24}{Support for optional attachments} +% \paragraph{Optional attachments.} Support for optional attachments. +% \begin{macro}{\prjInputUser} +% \begin{macro}{\prjIncludeUser} +% \begin{macro}{\addtoOptAttachments} +% User interface to project for \cs{input} and \cs{include}. These commands +% may be redefined, but they need to include the appropriate input/include +% command in them. The \cs{addtoOptAttachments} command is a way of optionally +% attaching a file without the input. +% \begin{macrocode} +\newcommand{\prjInputUser}[1]{\input{#1}} +\newcommand{\prjIncludeUser}[1]{\include{#1}} +\newcommand{\addtoOptAttachments}[1]{% + \g@addto@macro\AP@addtoAttachments{,#1}} +\newcommand{\getcNameFromFileName}[1]{\@nameuse{descrip4#1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% The main code for optional attachments. +% \begin{macrocode} +\def\AP@addtoAttachments{} +% \end{macrocode} +% The attachments are listing in a comma-delimited list. If there is a space following a comma, it may appear +% as part of the path of the next attachment. So, we'll get JavaScript to strip away any leading spaces to +% avoid the need to instruct the user to insert a \texttt{\%} if the attachment list is on multiple lines. +% \begin{macrocode} +\def\jsstrsps{replace(/^\string\s*/, "")} +\def\jsstrdotsp{replace(/\string\.\string\s*/g, ".")} +\ifoptattachments + \def\AP@writeOptAttach{% + \newwrite\AP@OptAttachlist + \immediate\openout \AP@OptAttachlist \jobname_oa.cut +% \end{macrocode} +% Define the optional attachments list command, |\APOptAttachments|. +% \begin{macrocode} + \immediate\write\AP@OptAttachlist{\string\def\string + \APOptAttachments{\AP@addtoAttachments}} + \immediate\closeout\AP@OptAttachlist} +% \end{macrocode} +% Write the optional attachments list (|\APOptAttachments|) at the end of the document. +% \begin{macrocode} + \AtEndDocument{\AP@writeOptAttach} +% \def\AP@addtoAttachments{} + \def\AP@pathInput#1{% + \addtoOptAttachments{#1}\prjInputUser{#1}} + \def\AP@pathInclude#1{% + \addtoOptAttachments{#1.tex}\prjIncludeUser{#1}} +% \end{macrocode} +% Input the optional attachments list (|\APOptAttachments|) here. +% \begin{macrocode} + \InputIfFileExists{\jobname_oa.cut}{% + \def\AP@next{\edef\aeb@attachments + {\aeb@attachments\APOptAttachments}}% + }{\let\AP@next\relax} + \AP@next +\else +% \end{macrocode} +% When \texttt{!optattachments} is taken, we use the user commands \cs{prjInputUser} and +% \cs{prjIncludeUser} versions. +% \begin{macrocode} + \def\AP@pathInput#1{\prjInputUser{#1}} + \def\AP@pathInclude#1{\prjIncludeUser{#1}} +\fi +% \end{macrocode} +% \DescribeMacro{\prjinput}\DescribeMacro{\prjinclude}These are the main +% commands for inputting project files where the files themselves are optionally +% attached. +% \begin{macrocode} +\ifoptattachmentsTaken + \def\prjinput{\hyper@normalise\AP@pathInput} + \def\prjinclude{\hyper@normalise\AP@pathInclude} +% \end{macrocode} +% The \cs{include} command makes the following comparison. +%\begin{verbatim} +% \@for\reserved@a:=\@partlist\do +% {\ifx\reserved@a\reserved@b\@tempswatrue\fi}% +%\end{verbatim} +% The elements from \cs{@parlist} they come from the \cs{includeonly} command. +% The argument of \cs{include} has been normalized using \cs{hyper@normalise} but +% the filenames listed in \cs{includeonly} have not. So the comparison can fail. +% We normalize the file list as well. +% +% When the \texttt{optattachments} is present in the option list, +% the definition of \cs{optattachmentsTaken} is \cs{relax}, hence, +% the redefinition occurs. +% \begin{macrocode} + \let\AP@includeonly\includeonly + \def\includeonly{\hyper@normalise\AP@includeonly} +\else + \def\prjinput{\prjInputUser} + \def\prjinclude{\prjIncludeUser} +\fi +% \end{macrocode} +% \paragraph*{Attaching files.} +% If either the two attachments keys is used, then we execute \cs{aeb@initAttachWrite}. +% \begin{macrocode} +\ifx\aeb@attachsource\@empty + \ifx\aeb@attachments\@empty + \else\aeb@initAttachWrite\fi +\else + \@ifundefined{aeb@attachmentswrite} + {\aeb@initAttachWrite}{} +\fi +% \end{macrocode} +% If \cs{aeb@attachsource} is non empty, go through the comma delimited list, and write to the +% cut file we just opened. +% +%\changes{v0.8i}{2008/10/08}{% +% Beginning with version 7.05, there is a \texttt{description} property. +% Prior to that, the value of \texttt{cname} was used for the description. +% I've added an additional line that sets the description equal to +% \texttt{cname} for 7.05 or later. +%} +%\changes{v1.4d}{2014/02/24}{% +% Within this and the next \cs{@for} look, added a test for the empty +% argument. +%} +% Some commands for setting \texttt{cName} and description. +% \begin{macrocode} +\def\ap@cName(#1){\csname aeb@aName@attach#1\endcsname} +\def\ap@cNamexdef(#1){\expandafter + \xdef\csname aeb@aName@attach#1\endcsname} +\def\ap@cDescript(#1){\csname aeb@aDescript@attach#1\endcsname} +\def\ap@cDescriptSource(#1){\csname aeb@aDescript@#1\endcsname} +\def\ap@cDescriptxdef(#1){\expandafter + \xdef\csname aeb@aDescript@attach#1\endcsname} +\def\ap@cDescriptSourcexdef(#1){\expandafter + \xdef\csname aeb@aDescript@#1\endcsname} +% \end{macrocode} +% We now process the list from the \texttt{attachsource} key. +% \begin{macrocode} +\ifx\aeb@attachsource\@empty\else + \edef\temp@expand{\noexpand\@for\noexpand\@@tmp:=\aeb@attachsource} + \temp@expand\do{% + \ifx\@@tmp\@empty\else + \expandafter\ap@strpspcs\@@tmp\@nil\edef\@@tmp{\to@nilarg}% + \ap@cDescriptSourcexdef(\@@tmp){\jobname.\@@tmp}% + \aeb@IWVO{\space\space\space\space + var retn=\string\importDataObject({% +% \end{macrocode} +% \changes{v1.7}{2015/07/01}{Changed cName from \cs{jobname.\cs{@@tmp}} to +% just \cs{@@tmp}} +% (2015/07/01) Changed cName from \cs{jobname.}\cs{@@tmp} to +% just \cs{@@tmp}. +% \begin{macrocode} + cName: "\@@tmp", + cDIPath: "\jobname.\@@tmp".\jsstrdotsp});}% + \aeb@IWVO{\space\space\space\space + if ( (app.viewerVersion>7) && retn ) +% \end{macrocode} +% \changes{v1.7}{2015/07/01}{Changed \texttt{"\cs{jobname.\cs{@@tmp}}"} to +% just \texttt{"\cs{@@tmp}"}} +% (2015/07/01) Changed \texttt{"\cs{jobname.\cs{@@tmp}}"} to +% just \texttt{"\cs{@@tmp}"} within argument of \texttt{this.getDataObject}. +% \begin{macrocode} + this.getDataObject("\@@tmp").description=% + "\string\ap@cDescriptSource(\@@tmp)".\jsstrdotsp;}% + \expandafter + \edef\csname aeb@aName@\@@tmp\endcsname{\jobname.\@@tmp}% + \fi + }% +\fi +% \end{macrocode} +% Similarly, if \cs{aeb@attachments} is non empty, go through the comma delimited list, and write to the +% cut file we just opened. +% \begin{macrocode} +\ifx\aeb@attachments\@empty\else +\typeout{\string\aeb@attachments: \aeb@attachments}% + \aeb@parsecnt=0 + \edef\temp@expand{\noexpand\@for\noexpand\@@tmp:=\aeb@attachments} + \temp@expand\do + {% + \ifx\@@tmp\@empty\else + \expandafter\ap@strpspcs\@@tmp\@nil\edef\@@tmp{\to@nilarg}% + \advance\aeb@parsecnt1\relax +% \end{macrocode} +% Set default definitions of the name and description +% \begin{macrocode} + \ap@cNamexdef(\the\aeb@parsecnt){attach\the\aeb@parsecnt}% + \ap@cDescriptxdef(\the\aeb@parsecnt)% + {AeB Attachment \the\aeb@parsecnt}% + \aeb@IWVO{\space\space\space\space + var retn=\string\importDataObject({% +% \end{macrocode} +%\changes{v1.7}{2015/07/01}{Remove \cs{aref} in \texttt{cName}} +% (2015/07/01) Remove \cs{aref} in \texttt{cName} +% \begin{macrocode} + cName:"\string\ap@cName(\the\aeb@parsecnt)",% + cDIPath: "\@@tmp".\jsstrsps});}% + \aeb@IWVO{\space\space\space\space + if ( (app.viewerVersion>7) && retn ) +% \end{macrocode} +%\changes{v1.7}{2015/07/01}{Remove \cs{aref} in first argument} +% (2015/07/01) Remove \cs{aref} in first argument +% \begin{macrocode} + this.getDataObject(% + "\string\ap@cName(\the\aeb@parsecnt)").description=% + "\string\ap@cDescript(\the\aeb@parsecnt)";}% + \expandafter +% \end{macrocode} +% We associate the filename (path) with the label \texttt{cName}. This makes it convenient +% to reference an attachment. We can say |\@usenname{descrip4<name>}|. Also defined +% a convenience command \cs{getcNameFromFileName} for that purpose; for example, +% |\getcNameFromFileName{<name>}|. +% \begin{macrocode} + \expandafter\xdef\csname descrip4\@@tmp\endcsname + {\noexpand\ap@cName(\the\aeb@parsecnt)}% + \fi + } +\fi +% \end{macrocode} +% Now, if \cs{aeb@attachmentswrite} is defined, which means we have attachments and we opened a stream, +% we'll close off the environment, and close the file. +% \begin{macrocode} +\@ifundefined{aeb@attachmentswrite}{} +{% + {\lccode`P=`\}\def\jsMsg{"Attachments error: " + + e.toString()}\lowercase{\aeb@IWVO{P catch(e) + { console.println( \jsMsg\space); }}}}% + \aeb@IWVO{\string\end{execJS}} + \immediate\closeout \aeb@attachmentswrite +} +% \end{macrocode} +% Create a little macro to input the file \cs{jobname\_attach.cut} at the end of the package. +% \begin{macrocode} +\def\aeb@inputAttachments{\@ifundefined{aeb@attachmentswrite}{} + {\InputIfFileExists{\jobname_attach.cut}% + {\typeout{Inputting attachments file}}% + {\typeout{Cannot find attachments file}}}% +} +% \end{macrocode} +% \subsection{Creating a PDF Package} +% Beginning with Version 8, there is a special "Package" interface to access attachments. +% The commands in this section support creating a PDF Package using the specified attachments. +% +% The \texttt{viewmode}\IndexKey{viewmode} has values of \texttt{details}, +% \texttt{tile}, \texttt{layout}, and \texttt{hidden}. +% \begin{macrocode} +\define@choicekey+{aebpdfpack}{viewmode}[\val\nr]% + {details,tile,layout,hidden}{% + \ifcase\nr\relax + \def\aeb@pdfpack@viewmode{/D}\or + \def\aeb@pdfpack@viewmode{/T}\or + \def\aeb@pdfpack@viewmode{/T}\or + \def\aeb@pdfpack@viewmode{/H}\fi +}{} +% \end{macrocode} +% The \texttt{initview}\IndexKey{initview} of the package. The value of \texttt{initview} +% is a label name of one of the attached files. +% \begin{macrocode} +\define@key{aebpdfpack}{initview}[]{\def\aeb@pdfpack@initview{#1}} +\let\aeb@pdfpack@initview\@empty +% \end{macrocode} +% \begin{macro}{\earlyAttachForPkgs} +% Use this command to package the attachments to the parent document. +% \begin{macrocode} +\newcommand{\earlyAttachForPkgs}{% +% \end{macrocode} +%\changes{v1.7}{2015/07/11}{Added \string\texttt{CollectionPreview} menu item to assure the Hidden view +% is displayed.} +% (2015/07/11) Recent versions of \textsf{Acrobat DC} seem not to support the Hidden view. There is no +% difference between Hidden and Tiles, so we use \texttt{'CollectionPreview'} +% menu item to force the viewer into Preview mode, which I'm assuming is the same +% as Hidden mode. +% \begin{macrocode} +if (this.collection!=null&&this.collection.initialView == "Hidden") +var hideto=app.setTimeOut("app.clearTimeOut(hideto);" + +"app.execMenuItem('CollectionPreview');",1); +\if@gopro +if(typeof _aebpro_attach == "undefined") +( app.viewerVersion > 8 ) ? % +aebTrustedFunctions(this,aebImportAnFDF,"aebpro_attach.fdf") : % +this.importAnFDF("aebpro_attach.fdf");\fi +% \end{macrocode} +% For Version XI (or prior), there seems to be a bug. When +% no initial view is specified, the cover sheet should be displayed. It is +% but is disappears after a moment in favor of the first listed attachment +% in the package. To compensate for this, we force the Cover Sheet to appear +% after 2 seconds (trial and error value). +% \begin{macrocode} +\ifisPDFPackage\ifx\aeb@pdfpack@initview\@empty^^J% +if(app.viewerVersion<15)^^J% +var pkto=app.setTimeOut("app.clearTimeOut(pkto);" ++"app.execMenuItem('CollectionShowRoot');",5000);\fi\fi} +% \end{macrocode} +% \changes{v1.7k}{2015/08/05}{Added a \cs{ifisPDFPackage} switch} +% (2015/08/05) Added a \cs{ifisPDFPackage} switch. +% \changes{v2.1}{2016/05/15}{Finalized changes in \string\cs{makePDFPackage} to accommodate +% non-Distiller workflows.} +% \begin{macrocode} +\newif\ifisPDFPackage\isPDFPackagefalse +\newcommand{\makePDFPackage}[1]{\isPDFPackagetrue + \setkeys{aebpdfpack}{viewmode=details,#1}% + \ifx\aeb@pdfpack@initview\@empty + \let\aeb@pdfpackage@initview\@empty + \else +% \end{macrocode} +% \changes{v1.7}{2015/07/01}{Removed \cs{aeb@exiii} and \cs{aref()}, +% replaced with \cs{expandafter} and argument.} +% (2015/07/01) Removed \cs{aeb@exiii} and \cs{aref()}, +% replaced with \cs{expandafter} and argument. +% \changes{v2.0}{2016/05/08}{Extend \string\cs{makePDFPackage} to include +% pdftex and xetex.} +% \begin{macrocode} + {\obeyspaces\sanitize@attach\gdef\aeb@pdfpackage@initview% +{/D<\expandafter\stringiiUnicode\aeb@pdfpack@initview\relax>}}% + \fi + \def\aeb@PDFPackageCode{/PageMode/UseAttachments% + /Collection<</Type/Collection% + \aeb@pdfpackage@initview/View\aeb@pdfpack@viewmode>>}% + \ifpdfmarkup + \def\aeb@setPDFPackage{\literalps@out{\AEB@psMrk{Catalog} + <<\aeb@PDFPackageCode>>/PUT pdfmark}}% + \else\ifpdf\def\aeb@setPDFPackage{% + \pdfcatalog{\aeb@PDFPackageCode}}\else + \ifxetex\def\aeb@setPDFPackage{\immediate + \@pdfm@mark{put @catalog <<\aeb@PDFPackageCode>>}}\else + \let\aeb@setPDFPackage\relax\PackageWarning{aeb_pro} + {The \string\makePDFPackage/string\makePDFPortfolio\space + is supported for\MessageBreak + dvips, pdftex, and xetex only}\fi\fi\fi +} +% \end{macrocode} +% \DescribeMacro{\makePDFPortfolio} is an alias for \cs{makePDFPackage}. The accepted +% name for a PDF Package is now a PDF Portfolio. +% \begin{macrocode} +\let\makePDFPortfolio\makePDFPackage +\@onlypreamble\makePDFPackage +% \end{macrocode} +% We check to see if there are any attachments, if there are, we'll +% import them early; useful for \cs{makePDFPackage} and for open events +% that cause the view to display a page other than the first one on opening. +% \begin{macrocode} +\let\aebp@attachments\aebp@Zero +\ifx\aeb@attachsource\@empty\else\let\aebp@attachments\aebp@One\fi +\ifx\aeb@attachments\@empty\else\let\aebp@attachments\aebp@One\fi +\ifx\aebp@attachments\aebp@One + \dev@addToDocOpen{\JS{\earlyAttachForPkgs}}% +\fi +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +% End of aebpro segment +%</aebpro> +%<*package> +\AtEndOfPackage{\@nameuse{aeb@inputAttachments}} +\AtBeginDocument{\@nameuse{aeb@setPDFPackage}} +\@ifpackageloaded{web}{} + {\def\aebwritelastpage{% + \immediate\write\@auxout{\string\expandafter\string\gdef + \string\csname\space aebLastPage\string\endcsname{\arabic{page}}}} + \AtEndDocument{\clearpage\addtocounter{page}{-1}\aebwritelastpage + \addtocounter{page}{1}}% +} +% End of package segment +%</package> +%<*unicode> +% \end{macrocode} +% \section{Support for linking to attachments.} +% +% \subsection{\texorpdfstring{\cs{ahyperref}, \cs{ahyperlink}, \cs{ahyperextract}} +% {\CMD{ahyperref}, \CMD{ahyperlink}, \CMD{ahyperextract}}} +% +% The \cs{ahyperref} command is for linking between parent and child, or +% between child and child. \cs{ahyperref} takes three arguments, the first optional +% and the second two required. +%\begin{verbatim} +% \ahyperref[<optargs>]{<label>}{<text>} +%\end{verbatim} +% where \texttt{<label>} is one defined by either \cs{autolabelNum} or \cs{labelName}. The +% \texttt{<text>} is the text to be typeset around the link. The optional arguments are defined +% and described below. +% \begin{itemize} +% \item \verb!goto=p2c,c2p,c2c!: The type of jump, parent to child, child to parent, and child to +% child. The default is \texttt{p2c} +% \item \texttt{page=<number>}: the page of the embedded document to jump to. Default is \texttt{0} +% \item \texttt{view=<value>}: the view to be used for the jump. Default is \texttt{Fit} +% \item \texttt{dest=<string>}: jump to a named destination. When this key has a value, the values +% of the keys \texttt{page} and \texttt{view} are ignored. +% \item \verb!open=usepref|new|existing!: open the attachment according to the user preferences, +% a new window, or the existing window. The default is \texttt{userpref} +% \item \verb!border=visible|invisible!: Determines whether a visible rectangle appears around the +% link. The default is \texttt{invisible} +% \item \verb!highlight=none|invert|outline|insert!: How the viewer highlights the link when the +% link is clicked. The default is \texttt{invert}. +% \item \texttt{bordercolor=r g b}: The color of the border when it is visible. The default is black. +% \item \verb!linestyle=solid|dashed|underlined!: The line style of the border when it is visible. +% The default is \texttt{solid} +% \item \texttt{textcolor=<color>}: the color of the text in the hypertext link. An empty +% value is equivalent to \cs{normalcolor}. +% \item \verb!linewidth=thin|medium|thick!: The line width when the border is visible. When invisible, +% this is set to a width of zero. The default is \texttt{thin} +% \item \texttt{preset=\cs{presetCommand}}: A convenience key. You can define some preset values, like so +%\begin{verbatim} +%\def\preseti{bordercolor={0 0 1},highlight=outline,border=visible,% +% linestyle=dashed} +%\end{verbatim} +% Then you can say, for example, +%\begin{verbatim} +%\ahyperref[dest={target1-s:intro},preset=\preseti]{target1}{Jump!} +%\end{verbatim} +% \end{itemize} +% \paragraph*{Key-value pairs of attachment links.} +% The following are the key-values of the optional first argument of \cs{ahyperref} +% \cs{hyperlink} and \cs{hyperextract}.\par\medskip +%\noindent +% The \texttt{page}\IndexKey{page} key, takes a zero-based page number. +% \begin{macrocode} +\define@key{ahref}{page}[0]{\def\ahref@page{#1}} +\def\ahref@page{0} +% \end{macrocode} +% The key \texttt{view}\IndexKey{view} represents an ``explicit destination,'' as termed by the PDF Ref, \S8.2.1. +%\begin{itemize} +% \item \texttt{/XYZ left top zoom} +% \item \texttt{/Fit} +% \item \texttt{/FitH top} +% \item \texttt{/FitV left} +% \item \texttt{/FitR left bottom right} +% \item \texttt{/FitB} +% \item \texttt{/FitBH top} +% \item \texttt{/FitBV left} +%\end{itemize} +% For the \texttt{view} key, enter view=Fit or view=XYB null null null, for example. The forward slash +% is added later. +% +% (2015/07) More recent advances allows \cs{fitpage}, \cs{fitvisible}, +% \cs{actualsize}, \cs{fitheight}, \cs{fitwidth}, and \cs{inheritzoom} to be used. +% These are defined in \textsf{insdljs}. +% +% Each of these is preceded by a page number. The page number is entered via the \texttt{page} +% key. +% +% If a named destination is given with the dest key, then the \texttt{view} and \texttt{page} are ignored. +% \begin{macrocode} +\def\ap@fslash{/} +\def\@isfirstslash#1#2\@nil{\def\arg@i{#1}\ifx\ap@fslash\arg@i + \else\edef\ahref@view@keyvalue{/\ahref@view@keyvalue}\fi} +\define@key{ahref}{view}[/Fit]{\edef\ahref@view@keyvalue{#1}% + \expandafter\@isfirstslash\ahref@view@keyvalue\@nil +} +\def\ahref@view@keyvalue{/Fit} +% \end{macrocode} +% The \texttt{dest}\IndexKey{dest} key +% \begin{macrocode} +\define@key{ahref}{dest}[]{\def\ahref@dest{#1}} +\let\ahref@dest\@empty +% \end{macrocode} +% The \texttt{open}\IndexKey{open} key takes values of \texttt{userpref}, \texttt{new}, and \texttt{existing}. +% \begin{macrocode} +\define@choicekey{ahref}{open}[\val\nr]{userpref,new,existing} +{% + \ifcase\nr\relax + \let\ahref@open@keyvalue\@empty\or + \def\ahref@open@keyvalue{/NewWindow true }\or + \def\ahref@open@keyvalue{/NewWindow false }\fi +}{} +\let\ahref@open@keyvalue\@empty +% \end{macrocode} +% The \texttt{border}\IndexKey{border} key takes values of \texttt{visible} and \texttt{invisible}. +% \begin{macrocode} +\define@choicekey{ahref}{border}[\val\nr]{visible,invisible} +{% + \ifcase\nr\relax + \def\ahref@border{0 0 1}% + \def\ahef@invisible@border{1}\or + \def\ahref@border{0 0 0}% W = 0 also? + \let\ahef@invisible@border\@empty\fi +}{} +% \end{macrocode} +% The \texttt{highlight}\IndexKey{highlight} key takes values of \texttt{none}, +% \texttt{invert}, \texttt{outline}, and \texttt{insert}. +% \begin{macrocode} +\define@choicekey{ahref}{highlight}[\val\nr]{none,invert,outline,insert} +{% + \ifcase\nr\relax + \let\ahref@highlight\@empty\or + \def\ahref@highlight{/H/I}\or + \def\ahref@highlight{/H/O}\or + \def\ahref@highlight{/H/P}\fi +}{} +% \end{macrocode} +% The \texttt{bordercolor}\IndexKey{bordercolor} key\par\medskip\noindent +% (2017/03/08) \cs{ahref@bordercolor} can be a named color, +% \changes{v2.8a}{2017/03/08}{\string\cs{ahref@bordercolor} can be a named color} +% \begin{macrocode} +\define@key{ahref}{bordercolor}[]{\def\ap@argi{#1}\ifx\ap@argi\@empty + \let\ahref@bordercolor\@empty\else + \HyColor@IfXcolor{\HyColor@XZeroOneThreeFour{#1} + {\ahref@bordercolor}{}{}} + {\edef\ahref@bordercolor{#1}}\fi +} % PDF color +\let\ahref@bordercolor\@empty +% \end{macrocode} +% The \texttt{linestyle}\IndexKey{linestyle} key takes values of \texttt{solid}, +% \texttt{dashed}, and \texttt{underlined}. +% \begin{macrocode} +\define@choicekey{ahref}{linestyle}[\val\nr]{solid,dashed,underlined} +{% + \ifcase\nr\relax + \def\ahref@linestyle@keyvalue{/S/S}\or + \def\ahref@linestyle@keyvalue{/S/D}\or % Dashed [0 0 1[3.0]] + \def\ahref@linestyle@keyvalue{/S/U}\fi +} +\def\ahref@dashedlinetyle{/S/D} +% \end{macrocode} +% The \texttt{linewidth}\IndexKey{linewidth} key takes values of \texttt{thin}, +% \texttt{medium}, and \texttt{thick}. +% \begin{macrocode} +\define@choicekey{ahref}{linewidth}[\val\nr]{thin,medium,thick} +{% + \ifcase\nr\relax + \def\ahref@linewidth{1}\or + \def\ahref@linewidth{2}\or + \def\ahref@linewidth{3}\fi +} +% \end{macrocode} +% The \texttt{goto}\IndexKey{goto} key takes values of \texttt{p2c}, +% \texttt{c2p}, and \texttt{c2c}. +% \begin{macrocode} +\define@choicekey{ahref}{goto}[\val\nr]{p2c,c2p,c2c} +{% + \ifcase\nr\relax + \global\let\targetDictionary\targetDictionary@pc\or + \global\let\targetDictionary\targetDictionary@cp\or + \global\let\targetDictionary\targetDictionary@cc\fi +}{} +% \end{macrocode} +% The \texttt{launch}\IndexKey{launch} key takes values of \texttt{save}, +% \texttt{view}, and \texttt{viewnosave}. +% \begin{macrocode} +\define@choicekey{ahref}{launch}[\val\nr]{save,view,viewnosave} + {\edef\ahref@launch@type{\nr}}{} +\def\ahref@launch@type{0}% +% \end{macrocode} +% The \texttt{preset}\IndexKey{preset} key +% \begin{macrocode} +\define@key{ahref}{preset}[]{\def\ahref@preset{#1}} +\let\ahref@preset\@mpty +% \end{macrocode} +% Color of the link text by command \DescribeMacro{\ahrefcolor}\cs{ahrefcolor} +% or as a key \texttt{textcolor}\IndexKey{textcolor}. +% \begin{macrocode} +\def\ahypertxtcolor#1{\def\ahrefcolor{#1}} +\def\ahrefcolor{red} +\define@key{ahref}{textcolor}[]{\def\ahrefcolor{#1}} +% \end{macrocode} +%\changes{v1.7}{2015/07/01}{Changed \cs{aeb@exiii} to \cs{expandafter}, changed +% \cs{aref(\#1)} to \texttt{\#1}.} +% (2015/07/01) Changed \cs{aeb@exiii} to \cs{expandafter}, changed +% \cs{aref(\#1)} to \texttt{\#1} in \cs{targetDictionary@pc} +% and \cs{targetDictionary@cc}. +% \begin{macrocode} +\def\targetDictionary@pc#1{% +/T<</N<\expandafter\stringiiUnicode#1\relax>/R/C>>} +\def\targetDictionary@cp#1{/T<</R/P>>} +\def\targetDictionary@cc#1{% +/T<</R/P/T<</N<\expandafter\stringiiUnicode#1\relax>/R/C>>>>} +% \end{macrocode} +% \begin{macro}{\factory@ahyperref@defaults} +% \begin{macro}{\setahyperDefaults} +% \begin{macro}{\resetahyperDefaults} +% The defaults, \cs{factory@ahyperref@defaults}, of \cs{ahyperref}, as indicated above in the descriptions of the keys. Can be redefined, I suppose. +% Perhaps the better approach is to use \cs{setahyperDefaults} to set the defaults, possibly overwriting the factory defaults. +% Use \cs{resetahyperDefaults} to cancel out the user defined defaults. You can also use the \texttt{preset} key for conveniently changing +% the attributes of the link. +% \begin{macrocode} +\def\factory@ahyperref@defaults{goto=p2c,page,dest,open=userpref,view,% + border=invisible,highlight=invert,linestyle=solid,linewidth=thin,% + bordercolor,textcolor=red,preset} +\newcommand{\setahyperDefaults}[1]{\def\aeb@setahyperrefDefaults{#1}} +\let\aeb@setahyperrefDefaults\@empty +\newcommand{\resetahyperDefaults}{% + \let\aeb@setahyperrefDefaults\@empty} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\ahyperref} +% \begin{macro}{\ahyperlink} +% The \cs{ahyperref} command links a parent to its embedded children, or a child to a child. Cool. +% \changes{v1.7}{2015/07/01}{Rewrite the link to stuff, we'll use \texttt{cName} rather than description +% to link to the attachments, this is how it should have been to begin with.} +% (2015/07/01) Rewrite the link to stuff, we'll use \texttt{cName} rather than description +% to link to the attachments, this is how it should have been to begin with. All changes +% dated as (2015/07/01) are the changes needed. +% \begin{macrocode} +\def\aeb@initahref#1{% + \edef\expand@setkeys{% + \noexpand\setkeys{ahref}{\factory@ahyperref@defaults}}% + \expand@setkeys + \ifx\aeb@setahyperrefDefaults\@empty\else +% \end{macrocode} +% For the \cmd{\setahyperrefDefaults} we do not allow \texttt{dest}, \texttt{goto}, +% \texttt{page}, or \texttt{preset}. +% \begin{macrocode} + \edef\expand@setkeys{\noexpand\setkeys{ahref}% + [dest,goto,page,preset]{\aeb@setahyperrefDefaults}}% + \expand@setkeys + \fi + \setkeys{ahref}{#1}% + \ifx\ahref@preset\@empty\else + \edef\expand@setkeys{% + \noexpand\setkeys{ahref}{\ahref@preset}}\expand@setkeys\fi + \let\ahref@dasharray\@empty + \ifx\ahref@linestyle@keyvalue\ahref@dashedlinetyle + \def\aeb@border@parameters{0 0 \ahref@linewidth[3.0]}% + \def\ahref@dasharray{/D[3.0]}% + \else + \edef\aeb@border@parameters{\ahref@border}% + \fi + \ifx\ahef@invisible@border\@empty\def\ahref@linewidth{0}\fi + \def\ahref@BS@Dict{/BS<<% + \ahref@dasharray\ahref@linestyle@keyvalue/W \ahref@linewidth>> + \ifx\ahref@bordercolor\@empty\else + /C[\ahref@bordercolor]\fi\ahref@highlight}% +} +\newcommand{\ahyperref}[3][]{% + \begingroup + \dl@preProcDefns + \def\u{\string\\u}% + \aeb@initahref{#1}% + \ifx\ahref@dest\@empty + \def\ahref@dest@keyvalue{% + /D[\ahref@page\space\ahref@view@keyvalue]}% + \else + \edef\ahref@dest@keyvalue{/D(\labelRef{\ahref@dest})}% + \fi + \aeb@ahref@setlink{#2}{#3}% +} +\newcommand{\ahyperlink}[3][]{% + \begingroup + \dl@preProcDefns + \def\u{\string\\u}% + \aeb@initahref{#1}% + \ifx\ahref@dest\@empty + \def\ahref@dest@keyvalue{% + /D[\ahref@page\space\ahref@view@keyvalue]}% + \else + \def\ahref@dest@keyvalue{/D(\ahref@dest)}% + \fi + \aeb@ahref@setlink{#2}{#3}% +} +\def\aeb@ahref@setlink#1#2{% + \ifx\ahrefcolor\@empty + \@eqlinktxtcolor{}\let\ahypercolor\@empty\else + \def\ahypercolor{\textcolor{\ahrefcolor}}\fi + \setLink[\Border{\aeb@border@parameters}% + \rawPDF{\ahref@BS@Dict}% + \A{\ahref@dest@keyvalue/S/GoToE% + \ahref@open@keyvalue\targetDictionary{#1}}]{\ahypercolor{#2}}% + \endgroup +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\ahyperextract} +% The \cs{ahyperextract} command extracts an embedded file from the parent +% to simple view the document, to save and view, or simply to save. The +% \texttt{open} key determines the resulting action. +% \begin{macrocode} +\newcommand{\ahyperextract}[3][] +{% + \begingroup\dl@preProcDefns + \def\u{\string\\u}% + \aeb@initahref{#1}% + \ifx\ahrefcolor\@empty + \@eqlinktxtcolor{}\let\ahypercolor\@empty\else + \def\ahypercolor{\textcolor{\ahrefcolor}}\fi + \setLink[\Border{\aeb@border@parameters}% + \rawPDF{\ahref@BS@Dict}% +% \end{macrocode} +%\changes{v1.7}{2015/07/01}{Removed \cs{aref(\#2)}, replaced with \texttt{\#2}} +% (2015/07/01) Removed \cs{aref(\#2)}, replaced with \texttt{\#2} +% \begin{macrocode} +% \A{\JS{this.exportDataObject({cName: "\aref(#2)",% + \A{\JS{this.exportDataObject({cName: "#2",% +nLaunch: \ahref@launch@type})}}]{\ahypercolor{#3}}% + \endgroup +} +% \end{macrocode} +% \end{macro} +% \subsection{Unicodes} +% \begin{macro}{\convertChriiUnicode} +% A simple command for mapping a character to its unicode +% \begin{macrocode} +\def\convertChriiUnicode#1#2{\csarg\gdef{uni@#1}{#2}}% +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +\convertChriiUnicode\space{0020} +\convertChriiUnicode{!}{0021} +{\@makeother\" +\convertChriiUnicode{"}{0022}} +%\convertChriiUnicode{"}{0022} % not available, but use \u0022 instead +\convertChriiUnicode{#}{0023} +\convertChriiUnicode{$}{0024} +{\@makeother\% +\convertChriiUnicode{%}{0025}} +\convertChriiUnicode{&}{0026} +\convertChriiUnicode{'}{0027} +\convertChriiUnicode{(}{0028} +\convertChriiUnicode{)}{0029} +\convertChriiUnicode{*}{002A} +\convertChriiUnicode{+}{002B} +\convertChriiUnicode{,}{002C} +\convertChriiUnicode{-}{002D} +\convertChriiUnicode{.}{002E} +\convertChriiUnicode{/}{002F} +\convertChriiUnicode{0}{0030} +\convertChriiUnicode{1}{0031} +\convertChriiUnicode{2}{0032} +\convertChriiUnicode{3}{0033} +\convertChriiUnicode{4}{0034} +\convertChriiUnicode{5}{0035} +\convertChriiUnicode{6}{0036} +\convertChriiUnicode{7}{0037} +\convertChriiUnicode{8}{0038} +\convertChriiUnicode{9}{0039} +\convertChriiUnicode{:}{003A} +\convertChriiUnicode{;}{003B} +\convertChriiUnicode{<}{003C} +\convertChriiUnicode{=}{003D} +\convertChriiUnicode{>}{003E} +\convertChriiUnicode{?}{003F} +\convertChriiUnicode{@}{0040} +\convertChriiUnicode{A}{0041} +\convertChriiUnicode{B}{0042} +\convertChriiUnicode{C}{0043} +\convertChriiUnicode{D}{0044} +\convertChriiUnicode{E}{0045} +\convertChriiUnicode{F}{0046} +\convertChriiUnicode{G}{0047} +\convertChriiUnicode{H}{0048} +\convertChriiUnicode{I}{0049} +\convertChriiUnicode{J}{004A} +\convertChriiUnicode{K}{004B} +\convertChriiUnicode{L}{004C} +\convertChriiUnicode{M}{004D} +\convertChriiUnicode{N}{004E} +\convertChriiUnicode{O}{004F} +\convertChriiUnicode{P}{0050} +\convertChriiUnicode{Q}{0051} +\convertChriiUnicode{R}{0052} +\convertChriiUnicode{S}{0053} +\convertChriiUnicode{T}{0054} +\convertChriiUnicode{U}{0055} +\convertChriiUnicode{V}{0056} +\convertChriiUnicode{W}{0057} +\convertChriiUnicode{X}{0058} +\convertChriiUnicode{Y}{0059} +\convertChriiUnicode{Z}{005A} +\convertChriiUnicode{[}{005B} +%\convertChriiUnicode{\}{005C} % not available, use unicode \u005C +\convertChriiUnicode{]}{005D} +\convertChriiUnicode{^}{005E} +\convertChriiUnicode{_}{005F} +\convertChriiUnicode{`}{0060} +\convertChriiUnicode{a}{0061} +\convertChriiUnicode{b}{0062} +\convertChriiUnicode{c}{0063} +\convertChriiUnicode{d}{0064} +\convertChriiUnicode{e}{0065} +\convertChriiUnicode{f}{0066} +\convertChriiUnicode{g}{0067} +\convertChriiUnicode{h}{0068} +\convertChriiUnicode{i}{0069} +\convertChriiUnicode{j}{006A} +\convertChriiUnicode{k}{006B} +\convertChriiUnicode{l}{006C} +\convertChriiUnicode{m}{006D} +\convertChriiUnicode{n}{006E} +\convertChriiUnicode{o}{006F} +\convertChriiUnicode{p}{0070} +\convertChriiUnicode{q}{0071} +\convertChriiUnicode{r}{0072} +\convertChriiUnicode{s}{0073} +\convertChriiUnicode{t}{0074} +\convertChriiUnicode{u}{0075} +\convertChriiUnicode{v}{0076} +\convertChriiUnicode{w}{0077} +\convertChriiUnicode{x}{0078} +\convertChriiUnicode{y}{0079} +\convertChriiUnicode{z}{007A} +%\convertChriiUnicode{{}{007B} % not available, use unicode \u007B +\convertChriiUnicode{|}{007C} +%\convertChriiUnicode{}}{007D} % not available, use unicode \u007D +{\@makeother~ +\convertChriiUnicode{~}{007E}} +% \end{macrocode} +% \begin{macro}{\EURO} +% \begin{macro}{\BSLASH} +% \begin{macro}{\LBRACE} +% \begin{macro}{\RBRACE} +% \begin{macro}{\DQUOTE} +% These characters are entered into the description parameter of \cs{autolabelNum} +% or \cs{labelName} as either as literal characters or as its unicode \cs{uXXXX}. +% When \cs{u} is detected \cs{@stringiiUnicode}, the command that converts the string +% to all unicode hex, it calls \cs{getRawUnicode} to get the next four characters, which +% should be XXXX, place them in the stream, followed by \cs{@stringiiUnicode} so as to +% continue the processing of the next character in the description string. I've placed +% an \cs{expandafter} in the definition of \cs{getRawUnicode} to allow the commands below +% to be used. Thus instead of using \cs{u20AC}, which might necessitate the user to +% look up the code, \verb!\u\EURO! can be used instead. Additional shortcut commands +% like these can be created. Except for \cs{EURO}, these are the ones \TeX{} has trouble +% processing. +% \begin{macrocode} +\def\EURO{20AC} +\def\BSLASH{005C} +\def\LBRACE{007B} +\def\RBRACE{007D} +\def\DQUOTE{0022} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% Display the Unicode encoding of a character +% +% \begin{macrocode} +\def\displayUnicode#1{\csname uni@#1\endcsname} +% \end{macrocode} +% \begin{macro}{\stringiiUnicode} +% This is the primary command for converting a string, which +% may contain \cs{uXXXX} control sequences into unicode encoding. +% The first four hex digits must be \texttt{FEFF} to signal that +% the hex represents unicode. +% \begin{macrocode} +\def\stringiiUnicode{FEFF\expandafter\@stringiiUnicode} +\def\@stringiiUnicode#1{% + \ifx#1\relax\else + \ifx#1\u\aeb@exiii\getRawUnicode + \else + \displayUnicode{#1}\aeb@exiii\@stringiiUnicode + \fi + \fi +} +\def\getRawUnicode{\expandafter\@getRawUnicode} +\def\@getRawUnicode#1#2#3#4{#1#2#3#4\@stringiiUnicode} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\unicodeStr} +% A convenience command for setting the initial value of a form field with unicode. +% Usage: +%\begin{verbatim} +%\labelName{myCoolIV}{\u0022\u20AC|e^\u007B\u005Cln(17)\u007D|$\u0022} +%\textField[\textSize{10}\textFont{MyriadPro-Regular} +% \uDV{\unicodeStr(myCoolIV)}\uV{\unicodeStr(myCoolIV)} +%]{myCoolIV}{1.5in}{12bp} +%\end{verbatim} +% First you set the string using \cs{labelName}. The argument for \cs{unicodeStr} +% is delimited by parentheses, the argument itself is the label defined with +% \cs{labelName}. +% +%\medskip\noindent +% (2015/07/12) If \texttt{\#1} does not define a recognizable label (defined by \cs{labelName} +% we assume \texttt{\#1} is raw hex digits. +% \begin{macrocode} +\def\unicodeStr(#1){\expandafter + \ifx\csname aeb@aDescript@#1\endcsname\relax + FEFF#1\else\aeb@exiii\stringiiUnicode\aref(#1)\relax\fi} +% \end{macrocode} +% \end{macro} +% +% \subsection{\texorpdfstring{\cs{labelName} and \cs{autolabelNum}} +% {\CMD{labelName} and \CMD{autolabelNum}}} +% +% \begin{macro}{\autolabelNum} +% \begin{macro}{\autolabelNum*} +% \begin{macro}{\labelName} +% Commands for defining the description string for the attachments. +% It is important that the description of the attached file, and the reference +% to in in the \texttt{/GoToE} exactly match. The commands define here set up the +% mapping between a ``\LaTeX'' label and the description. These commands also allow +% the document author to overwrite the default attachment descriptions. Usage: +%\begin{enumerate} +%\item\verb!\autolabelNum[<label>]{<attachment_number>}! +%\item\verb!\autolabelNum*[<label>]{<attachment_number>}{<description>}! +%\item\verb!\labelName{<label>}{<description>}! +%\end{enumerate} +% \cs{autolabelNum} and \cs{autolabelNum*} are used with attachments attached using the +% \texttt{attachments} option, while \cs{labelName} is used it the document author attached +% a file using the \texttt{docassembly} environment. \cs{labelName} is also used by +% \cs{autolabelNum} and \cs{autolabelNum*} to make definitions, in that respect, \cs{labelName} +% is the low-level command for setting up the mappings and definitions. +% \begin{macrocode} +\def\ucspace{\u0020} +\begingroup\catcode`\"=\active \gdef\DQ{\string\"}% + \gdef\@handledblquotes{\catcode`\"=\active\def"{\DQ}}% + \toks0=\expandafter{\DLspecialDefs\@handledblquotes}% + \xdef\DLspecialDefs{\the\toks0}% +\endgroup +% \end{macrocode} +%\changes{v1.7l}{2015/08/07}{Add the switch \cs{ifHandleDblQuotes} switch} +% (2015/08/07) Add the switch \cs{ifHandleDblQuotes} switch. +% \begin{macrocode} +\newif\ifHandleDblQuotes \HandleDblQuotesfalse +\def\sanitize@attach{\ifHandleDblQuotes\@handledblquotes\fi% +\@makeother\#\@makeother\$\@makeother\%\@makeother~} +{\obeyspaces\gdef\getdscrptCont#1{\gdef\aebp@description{#1}% +\aeb@labelName}% +\gdef\getdscrptStrCont#1{\gdef\aebp@description{#1}% +\aeb@labelNamestar}}% +% \end{macrocode} +% \changes{v1.7}{2015/07/05}{Modified the commands \string\cs{labelName} and \string\cs{labelName@star} to +% gobble up any spaces between arguments before we switch to \string\cs{obeyspaces}.} +% (2015/07/05) Modified \cs{labelName} and \cs{labelName@star} to +% gobble up any spaces between arguments before we switch to \cs{obeyspaces}. +% \begin{macrocode} +\let\aeb@isFromAutoLabelNum\aebp@Zero +\def\labelName#1{\bgroup\let\aeb@isFromAutoLabelNum\aebp@Zero + \@for\x:=ABCDEFabcdef\do{\@makeother\x}% + \def\aebp@labelname{#1}\@ifnextchar\bgroup{\labelName@i}{}} +% \end{macrocode} +%\changes{v1.7k}{2015/08/02}{Added \cs{labelName@a}} +% (2015/08/02) \cs{autoLabelNum} used to call \cs{labelName}, not it calls +% \cs{labelName@a}, which sets a switch to notify \cmd{\aeb@labelName} of the origins +% of the call. +% \begin{macrocode} +\def\labelName@a#1{\bgroup\let\aeb@isFromAutoLabelNum\aebp@One + \def\aebp@labelname{#1}\@ifnextchar\bgroup{\labelName@i}{}} +\def\labelName@i{\obeyspaces\sanitize@attach\getdscrptCont}% +\def\labelName@star#1{\bgroup\@for\x:=ABCDEFabcdef\do{\@makeother\x}% + \def\aebp@labelname{#1}\@ifnextchar\bgroup{\labelName@star@i}{}}% +\def\labelName@star@i{\obeyspaces\sanitize@attach\getdscrptStrCont}% +\newcommand{\autolabelNum}{% + \@ifstar{\aeb@autoLabelNumstar}{\aeb@autoLabelNum}} +\newcommand\aeb@autoLabelNum[2][]{\def\alnargi{#1}% + \def\@thisattachnum{#2}% + \ifx\alnargi\@empty + \def\aeb@next{% + \labelName@a{attach#2}{AeB\space Attachment\space #2}}% + \else + \def\aeb@next{% + \labelName@a{#1}{AeB\space Attachment\space #2}}% + \fi + \aeb@next% +} +\newcommand{\aeb@autoLabelNumstar}[2][]{% + \def\alnargi{#1}\gdef\@thisattachnum{#2}% + \ifx\alnargi\@empty\def\aeb@next{\labelName@star{attach#2}}\else + \def\aeb@next{\labelName@star{#1}}\fi + \aeb@next% +} +\def\aeb@labelName{% +% \end{macrocode} +% \changes{v1.7k}{2015/08/02}{Added additional logic to \cs{aeb@labelName}} +% (2015/08/02) The definitions differ depending on whether it comes from +% the command \cs{autoLabelNum} or from \cs{labelNum}. +% \begin{macrocode} + \if\aeb@isFromAutoLabelNum\aebp@One + \global\csarg\let + {aeb@aDescript@attach\@thisattachnum}\aebp@description + \global\csarg\let + {aeb@aName@attach\@thisattachnum}\aebp@labelname + \else + \global\csarg\let + {aeb@aDescript@\aebp@labelname}\aebp@description + \global\csarg\let + {aeb@aName@\aebp@labelname}\aebp@labelname\fi\egroup} +\def\aeb@labelNamestar{% + \global\csarg\let + {aeb@aDescript@attach\@thisattachnum}\aebp@description + \global\csarg\let{aeb@aName@attach\@thisattachnum}\aebp@labelname + \global\csarg\let{aeb@aDescript@\aebp@labelname}\aebp@description + \global\csarg\let{aeb@aName@\aebp@labelname}\aebp@labelname\egroup} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% We need a general verbatim write environment, here is the one used by \textsf{exerquiz} and several other packages. +% If \textsf{exerquiz} is loaded, no need to redefine it. +% \begin{macrocode} +\@ifpackageloaded{exerquiz}{} +{% + \def\verbatimwrite{\@bsphack + \let\do\@makeother\dospecials + \catcode`\^^M\active\catcode`\^^I=12% + \def\verbatim@processline{% + \immediate\write\verbatim@out + {\the\verbatim@line}}% + \verbatim@start} + \def\endverbatimwrite{\@esphack} +} +% \end{macrocode} +% \begin{environment}{attachmentNames} +% Enclose the \cs{labelName} and \cs{autolabelNum} commands this environment, which writes +% it contents verbatim to the file \cs{jobname\_xref.cut} and inputs it back in. Child files can input this +% file to get the labels assigned for them by the parent document. +% \begin{macrocode} +\newenvironment{attachmentNames}{% + \newwrite \aeb@attachments@xref + \immediate\openout \aeb@attachments@xref \jobname_xref.cut + \let\verbatim@out\aeb@attachments@xref +% \end{macrocode} +%\changes{v1.7l}{2015/08/07}{Set \cs{ifHandleDblQuotes} to true} +% (2015/08/07) Set \cs{ifHandleDblQuotes} to true, added a group. +% \begin{macrocode} + \immediate\write\verbatim@out{\string\begingroup + \string\HandleDblQuotestrue}% + \verbatimwrite}{% + \endverbatimwrite + \immediate\write\verbatim@out{\string\endgroup}% + \immediate\closeout \aeb@attachments@xref + \aftergroup\aeb@Input@xref} +\def\aeb@Input@xref{\InputIfFileExists{\jobname_xref.cut}{}{}} +% \end{macrocode} +% \end{environment} +% \begin{macrocode} +% End of unicode segment +%</unicode> +% \end{macrocode} +% \texttt{(2013/04/01)} The \texttt{createicon} block separates out the +% import icon macros, doc and pre-\texttt{docassembly} stuff. +%\changes{v1.4b}{2013/04/01}{The \texttt{createicon} block separates the +%import icon macros, doc and pre-\texttt{docassembly} stuff.} +% \begin{macrocode} +% Begin aebpro and createicon segments +%<*aebpro|createicon> +% \end{macrocode} +% +% \section{Document Assembly Methods} +% Special commands and environment to take advantage of \app{Acrobat}'s extensive +% library of security restricted methods. It is assumed the document author has properly +% installed \texttt{aeb\_pro.js}. +% +% \subsection{The \texttt{docassembly} Environment} +% +% \begin{environment}{docassembly} +% This is a wrapper environment for the \texttt{execJS} environment of the +% \textsf{insDLJS} Package. Place JavaScript lines in this environment and +% the script will execute one time after the file has been distilled and opened +% in Acrobat Pro for the fist time. +% \begin{macrocode} +\newenvironment{docassembly}{% +\execJS{docassembly} +}{\endexecJS} +% \end{macrocode} +% \end{environment} +% \subsection{Supported Assembly JS API} +% +% These are convenience commands -- called JavaScript helper commands -- to +% executing security restricted JavaScript. The JS methods are defined in the +% \texttt{aeb\_pro.js} file, kept as folder JavaScript. These commands are +% executed in a verbatim environment where `\verb!\!' is still the escape +% character. Each of the JavaScript helper commands expects a left +% parenthesis `\texttt{(}' following the command name \emph{on the +% same line} as the command name.\footnote{This requirement is consistent with JavaScript function usage.} +% See the example below for correct usage. +%\begin{verbatim} +%\begin{docassembly} +%\addWatermarkFromFile({ +% bOnTop:false, +% cDIPath:"/C/AcroTeX/AcroPackages/ManualBGs/Manual_BG_Print_AeB.pdf" +%}); +%\end{docassembly} +%\end{verbatim} +% For each of the methods below, see the \textsl{JavaScript for Acrobat API Reference}. +% +%\medskip\noindent The command \cs{theDocObject} is normally set to \texttt{this}, meaning +% the current document. You may need to set it to some other doc object if you are trying to +% access a doc object other than the current one. +% \par\medskip\noindent +% Revised all these function that use \cs{theDocObject}; the revisions allow you to change +% the use of \cs{theDocObject}. The following are support commands for changing \cs{theDocObject} +% from within the \texttt{docassembly} environment. +% \changes{v2.5}{2016/08/03}{Revised all these function that use \string\cs{theDocObject}.} +% \begin{macro}{\chngDocObjectTo} +% All the JavaScript helper commands use \cs{theDocObject}, which is defined to be the \texttt{this} +% object. To change it within the \env{docassembly} environment is difficult. The next command +% aids in that problem. +% \begin{macrocode} +\let\ap@mrk\@empty +\def\ap@gobtocomma#1,{} +\providecommand\chngDocObjectTo[2]{% + \def#1##1\ap@mrk{#2,\ap@gobtocomma##1}} +% \end{macrocode} +% \end{macro} +% The above defines a new command given by \texttt{\#1}. The command has one argument which is all content +% up to the terminating mark \cs{sp@mrk}. The trick to removing \cs{thisDocObject} and replacing it with +% \texttt{\#2}, in the above definition, we insert `\texttt{(\#2}' followed by \cs{ap@gobtocomma}, which absorbs +% \cs{thisDocObject,} (absorbs everything through the first comma), followed by all content (\texttt{\#\#1}); the second \cs{@gobble} absorbs the left +% parenthesis that opens the argument. +% \begin{macrocode} +\def\ap@TF{aebTrustedFunctions} +% \end{macrocode} +% An example of usage of \cs{chngDocObject} is \verb~\chngDocObjectTo{\newDO}{doc}~ +% expanded above the \texttt{docassembly} environment. Later, we can say, +%\begin{verbatim} +% \chngDocObjectTo{\newDO}{doc} +% \begin{docassembly} +% ... +% \docSaveAs\newDO({ cPath: _path }); +% ... +% \end{docassembly} +%\end{verbatim} +%That is, it is placed immediately after any of the commands below that uses \cs{theDocObject}. +% \begin{macro}{\theDocObject} +% This command is used in the definition of all JavaScript helper commands, as seen in the +% definition of \cs{DeclareJSHelper} below. It is set to the doc object \texttt{this}. It can +% be changed using \cs{chngDocObjectTo}, as described above. +% \begin{macrocode} +\def\theDocObject{this} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\DeclareJSHelper} +% A general purpose command for defining what I am calling JavaScript helper commands. +% \begin{macrocode} +\providecommand\DeclareJSHelper[2]{% + \def#1##1({\ap@TF(##1\theDocObject,#2,\ap@mrk}} +% \end{macrocode} +% For example, we declare |\DeclareJSHelper{\docSaveAs}{aebDocSaveAs}| below, the declaration defines a new command, +% \cs{docSaveAs}: +%\begin{verbatim} +% \def\docSaveAs#1({\ap@TF(#1\theDocObject,aebDocSaveAs,\ap@mrk}} +%\end{verbatim} +% Note that the argument of \cs{docSaveAs} is delimited by the left parenthesis, thus \texttt{\#1} is everything through that opening +% parenthesis. This approach allows more flexibility in the definition, there can be spaces following the +% command name |\docSaveAs ({path: _path})|, for example. +% \end{macro} +% \begin{macrocode} +% End aebpro and createicon segments +%</aebpro|createicon> +%<*aebpro> +% \end{macrocode} +% \begin{macro}{\addWatermarkFromFile} +% This is the method \texttt{Doc.addWatermarkFromFile}. +% \begin{macrocode} +\DeclareJSHelper{\addWatermarkFromFile}{aebAddWatermarkFromFile} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +% End aebpro segment +%</aebpro> +%<*aebpro|createicon> +% \end{macrocode} +% \begin{macro}{\importIcon} +% This is the method \texttt{Doc.importIcon}. +% \begin{macrocode} +\DeclareJSHelper{\importIcon}{aebImportIcon} +% \end{macrocode} +% \begin{macrocode} +% End aebpro and createicon segments +%</aebpro|createicon> +%<*aebpro> +% \end{macrocode} +% \end{macro} +% \begin{macro}{\importSound} +% This is the method \texttt{Doc.importSound}. +% \begin{macrocode} +\DeclareJSHelper{\importSound}{aebImportSound} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\appopenDoc} +% This is the method \texttt{app.openDoc}. +% \begin{macrocode} +\DeclareJSHelper{\appopenDoc}{aebAppOpenDoc} +% \end{macrocode} +% \end{macro} +% This is the method \texttt{Doc.saveAs}. +% \changes{v2.5}{2016/08/31}{Added \string\cs{docSaveAs}} +% \begin{macro}{\docSaveAs} +% This is the document method \texttt{Doc.saveAs}. +% \begin{macrocode} +\DeclareJSHelper{\docSaveAs}{aebDocSaveAs} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\insertPages} +% This is the method \texttt{Doc.insertPages}. +% \begin{macrocode} +\DeclareJSHelper{\insertPages}{aebInsertPages} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\createTemplate} +% This is the method \texttt{Doc.createTemplate}. +% \begin{macrocode} +\DeclareJSHelper{\createTemplate}{aebCreateTemplate} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\importDataObject} +% This is the method \texttt{Doc.importDataObject}. +% \begin{macrocode} +\DeclareJSHelper{\importDataObject}{aebImportDataObject} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\executeSave} +% To save the document, use at the \emph{end of the doc assembly environment}. Usage: +% \verb!\executeSave()!. The \cs{@gobble} used below absorbs the comma that is placed immediately +% after the second argument by \cs{DeclareJSHelper}. +% \begin{macrocode} +\DeclareJSHelper{\executeSave}{aebSaveAs,"Save"\@gobble} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\extractPages} +% API to extract pages from a newly formed document. +% \begin{macrocode} +\DeclareJSHelper{\extractPages}{aebExtractPages} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\mailDoc} +% Used by eEnvelope to programmatically mail a document. +% \begin{macrocode} +\DeclareJSHelper{\mailDoc}{aebMailDoc} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\sigInfo} +% \begin{macro}{\signatureSign} +% \begin{macro}{\signatureSetSeedValue} +% The \cs{signInfo} command is used for entering signing formation into what will +% become an object. \cs{signatureSign} takes no arguments, but uses the info +% entered by \cs{signInfo}. An example is +%\begin{verbatim} +%\begin{docassembly} +%\signInfo{ +% cSigFieldName: "sigOfDPS", ohandler: security.PPKLiteHandler, +% cert: "D_P_Story.pfx", password: "dps017", +% oInfo: { location: "Niceville, FL", +% reason: "I am approving this document", +% contactInfo: "dpstory@acrotex.net", +% appearance: "My Signature" } +%}; +%\signatureSign +%\end{docassembly} +%\end{verbatim} +% The \cs{sigInfo} command is a latex interface to creating the +% \texttt{oSigInfo} object. +% \begin{macrocode} +\newcommand{\sigInfo}{var oSigInfo=} +\def\sigFieldObj(#1){var oSigField=this.getField(#1)} +% \end{macrocode} +% For the \cs{signatureSetSeedValue}, the field object is required. +% This function assumes that the JavaScript variable \texttt{oSigField} +% is the field object. For examle, +%\begin{verbatim} +%\begin{docassembly} +%\sigFieldObj("sigOfDPS"); +%\signatureSetSeedValue({ +% lockDocument:true, +% appearanceFilter:"My Signature", +% reasons: ["This is a reason", "This is a better reason"], +% flags:0x80|0x100|0x8 +%}); +%\end{docassembly} +%\end{verbatim} +% The signatureSetSeedValue() methods seeds a signature field with various default values +% available to the signer. +%\begin{verbatim} +%\begin{docassembly} +%var sv={ +% mdp: "defaultAndComments", +% reasons: ["This is a reason", "This is a better reason"], +% flags:0x80|0x100|0x8 +%}; +%\sigFieldObj("sigOfDPS"); +%\signatureSetSeedValue(sv); +%\end{docassembly} +%\end{verbatim} +% \begin{macrocode} +\def\signatureSetSeedValue#1{% + \ap@TF( oSigField, aebSignatureSetSeedValue, } +% \end{macrocode} +% The function \cs{signatureSign} takes the info in the \texttt{oSigInfo} object, +% gets the security handler object, logs into the handler, calls +% \texttt{signatureSetSeedValue} if the \texttt{sv} property is in the +% \texttt{oSigInfo} object, and signs the field. +% \begin{macrocode} +\begin{defineJS}[\def\defineJSjsR{^^J}]{\signatureSign} +if ( typeof oSigInfo.oHandler=="undefined" ) + oSigInfo.oHandler=security.PPKLiteHandler; +var engine=aebTrustedFunctions( security, + aebSecurityGetHandler, oSigInfo.oHandler ); +var path2Cert = (typeof oSigInfo.path2Cert == "undefined") ? + aebTrustedFunctions( this, aebAppGetPath, + {cCategory:"user"} )+"/Security"+"/"+oSigInfo.cert : + oSigInfo.path2Cert; +aebTrustedFunctions( engine, aebSecurityHandlerLogin, + { cPassword: oSigInfo.password, cDIPath: path2Cert}); +var oSigField = this.getField(oSigInfo.cSigFieldName); +oSigInfo.oInfo.password=oSigInfo.password; +if ( typeof oSigInfo.sv!="undefined" ) { + for (var o in oSigInfo.sv ) + oSigInfo.oInfo[o]=oSigInfo.sv[o]; +} +var oSigArgs={ oSig: engine, oInfo: oSigInfo.oInfo }; +if ( typeof oSigInfo.cLegalAttest!="undefined" ) + oSigArgs.cLegalAttest=oSigInfo.cLegalAttest; +if ( typeof oSigInfo.cDIPath!="undefined") + oSigArgs.cDIPath=oSigInfo.cDIPath; +if ( typeof oSigInfo.bUI!="undefined") + oSigArgs.bUI=oSigInfo.bUI; +aebTrustedFunctions( oSigField, aebSignatureSign, oSigArgs ); +\end{defineJS} +% \end{macrocode} +% \begin{macro}{\certifyInvisibleSign} +% This command uses the trusted version of \texttt{certifyInvisibleSign} to sign. The command +% requires that \cs{sigInfo} is populated appropriately. +%\begin{verbatim} +%\begin{docassembly} +%\sigInfo{ +% cert: "DonStory.pfx", password: "myPassword", +% cLegalAttest: "Certified using JavaScript", +% bUI:false, +% oInfo: { +% location: "Niceville, FL", +% reason: "I am certifying this document", +% mdp: "defaultAndComments", +% } +%}; +%\certifyInvisibleSign +%\end{docassembly} +%\end{verbatim} +% \begin{macrocode} +\begin{defineJS}[\def\defineJSjsR{^^J}]{\certifyInvisibleSign} +if ( typeof oSigInfo.oHandler=="undefined" ) + oSigInfo.oHandler=security.PPKLiteHandler; +var engine=aebTrustedFunctions( security, + aebSecurityGetHandler, oSigInfo.oHandler ); +var path2Cert=aebTrustedFunctions( this, aebAppGetPath, + {cCategory:"user"} )+"/Security"+"/"+oSigInfo.cert; +aebTrustedFunctions( engine, aebSecurityHandlerLogin, + { cPassword: oSigInfo.password, cDIPath: path2Cert}); +oSigInfo.oInfo.password=oSigInfo.password; +var oSigArgs={ oSig: engine, oInfo: oSigInfo.oInfo }; +if ( typeof oSigInfo.cLegalAttest!="undefined" ) + oSigArgs.cLegalAttest=oSigInfo.cLegalAttest; +if ( typeof oSigInfo.cDIPath!="undefined") + oSigArgs.cDIPath=oSigInfo.cDIPath; +if ( typeof oSigInfo.bUI!="undefined") + oSigArgs.bUI=oSigInfo.bUI; +aebTrustedFunctions( this, aebCertifyInvisibleSign, oSigArgs ); +\end{defineJS} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macrocode} +% End aebpro segment +%</aebpro> +%<*aebpro|createicon> +% \end{macrocode} +% \subsection{Pre-docassembly Commands} +% +% In this section, we'll gather some ``useful'' commands +% for combining several \texttt{docassembly} tasks together. +% The \texttt{docassembly} environment is a partial-verbatim +% environment, expansion is severely limited. (\verb!\! is +% the escape sequence, but \verb!{}! are no longer grouping characters; hence +% macros with no argument can be expanded.) The trick is to expand +% before placing the lines in the \texttt{docassembly} environment. +% +% \subsubsection{Import and Place Images} +% +% \begin{macro}{\declareImageAndPlacement} +% With this command, the document author can import images (icons) +% into the document give them names, and associate the image with a +% push button, specifically, once created by the \cs{placeImage} +% command, defined below. The command may be used several times, once +% for each image (icon) that is to be embedded and placed. +% +% This command should appear outside the \texttt{docassembly} environment. +% +% In the example below, give an image a name manAvatar, specify the +% path (\texttt{man1.pdf}) and list the names of the push buttons +% (ones created by \cs{placeImage}) where this image is to appear as +% a button face. +%\begin{verbatim} +% \declareImageAndPlacement +% { +% name=manAvatar,path=man1.pdf,placement={Avatar1,Avatar2} +% } +%\end{verbatim} +%\par\medskip\noindent +%The macro \cs{@importIconToks} will contain all JavaScript the commands created +% by the command \cs{declareImageAndPlacement}. \cs{aebp@image@cnt} is used +% for automatically generating a name if one is not given. +% \begin{macrocode} +\let\predocassemJS\@empty +\def\aeb@image@cnt{0} +% \end{macrocode} +% These keys are^^A +% valid for the argument of \cs{declareImageAndPlacement}: +% name, path, and placement are required; if the image is a PDF, \texttt{page=0} is the +% default, otherwise, you can specify from which page the PDF image is to be +% extracted from the PDF file. +% \IndexKey{name}\IndexKey{path}\IndexKey{page}\IndexKey{placement}\IndexKey{embedonly}% +% \IndexKey{firstpage}\IndexKey{lastpage}^^A +% \begin{macrocode} +\define@key{importIcons}{name}[]{\def\importIcons@name{#1}} +\define@key{importIcons}{path}[]{\def\importIcons@path{#1}} +\define@key{importIcons}{page}[]{\def\importIcons@page{#1}} +\define@key{importIcons}{placement}[]{\def\importIcons@placement{#1}} +\define@boolkey{importIcons}{embedonly}[true]{} +\define@key{importIcons}{firstpage}[]{\def\importIcons@firstpage{#1}} +\define@key{importIcons}{lastpage}[]{\def\importIcons@lastpage{#1}} +% \end{macrocode} +% The next two macros parse \cs{importIcons@placement} after it has been +% broken down into its comma-delimited parts. We pick off the optional +% argument using \cs{aebp@getFace}, then we call \cs{aebp@getPlacement} to +% get the field name. These are executed from within \cs{declareImageAndPlacement} +% below. +% +% If there is no optional argument, the default is 0, for the normal appearance state. +% \begin{macrocode} +\newcommand{\aebp@getFace}[1][0]{% + \def\importIcons@face{#1}\aebp@getPlacement} +\def\aebp@getPlacement#1\@nil{\def\importIcons@fieldname{#1}% + \expandafter\ap@strpspcs\importIcons@fieldname\@nil + \edef\importIcons@fieldname{\to@nilarg}% +} +% \end{macrocode} +% The command \cs{declareImageAndPlacement} takes one argument, key-value +% pairs as described above. This command may be use many times, once for +% each image. +% \begin{macro}{\declareMultiImages} +% Here is another macro, created after \cs{declareImageAndPlacement}, +% that enables the declaration of multiple images and placements. +% The following is an example of usage: +%\begin{verbatim} +%\declareMultiImages{% +% {name=manAvatar,path=man1.pdf,placement={Avatar1,Avatar2}} +% {path=girl.png,placement={Avatar3,Avatar4}} +% {path=AcroFord.jpg,placement=AcroFord} +% {path=scot.gif,placement=Scot} +%} +%\end{verbatim} +% (9/24/2009) Now you can enter the face number as an optional argument +% in the placement value: \texttt{[0]} (default, normal icon), \texttt{[1]} (down icon) +% \texttt{[2]} (rollover icon). The optional argument precedes the field name. For Example +%\begin{verbatim} +%\declareMultiImages +%{% +% {path=graphics/man1.pdf,placement={Avatar1,Avatar2}} +% {path=graphics/girl.png,placement={[2]Avatar1,[2]Avatar2}} +%} +%\end{verbatim} +% \begin{macrocode} +\newcommand{\declareMultiImages}[1]{% + \edef\@tforExp{\noexpand\@tfor\noexpand\@dipArgs:=#1}% + \@tforExp\do{% + \expandafter\declareImageAndPlacement + \expandafter{\@dipArgs}% + }% +} +% \end{macrocode} +% \end{macro} +% The definition of \cs{declareImageAndPlacement}. Keys recognized are +% defined above: \texttt{name}, \texttt{path}, \texttt{page}, \texttt{placement}. +% \begin{macrocode} +\newcommand{\declareImageAndPlacement}[1]{% + \edef\@tempexp{\noexpand\setkeys{importIcons}{name,path,page,% + placement,embedonly=false,#1}}\@tempexp + \ifx\importIcons@name\@empty{\count0=\aeb@image@cnt + \advance\count0by1\relax\xdef\aeb@image@cnt{\the\count0}}% + \edef\importIcons@name{aebImage\aeb@image@cnt}\fi + \ifx\importIcons@path\@empty + \PackageError{aeb_pro}{The `path' key is required} + {Please give the path of the icon.}\fi + \ifx\importIcons@placement\@empty\ifKV@importIcons@embedonly\else + \PackageWarningNoLine{aeb_pro}{% + The `placement' key was not found for the\MessageBreak + image named "\importIcons@name".\MessageBreak + Specify this key, or insert the image manually in\MessageBreak + the docassembly environment.}\fi\fi + \xdef\predocassemJS{\predocassemJS + var retn=\importIcon({cName:"\importIcons@name",% + cDIPath:"\importIcons@path"% + \ifx\importIcons@page\@empty\else,% + nPage:\importIcons@page\fi});^^J% + if ( retn==-1 ) console.println("The file + \string\"\importIcons@path\string\" could not be opened.");^^J% + if ( retn==-2 ) console.println("Selected page + (page=\importIcons@page) for \string\"\importIcons@path\string\" + is invalid.");^^J}% + \ifx\importIcons@placement\@empty\else + \@for\@fieldname:=\importIcons@placement\do{% + \expandafter\aebp@getFace\@fieldname\@nil + \xdef\predocassemJS{\predocassemJS + var f = this.getField("\importIcons@fieldname");^^J% + if ( f == null ) console.println("The field + \string\"\importIcons@fieldname\string\" + does not exist.");^^J% + try { f.buttonSetIcon(this.getIcon("\importIcons@name"),% + \importIcons@face); } + catch(e){};^^J}% + }% + \fi +} +\@onlypreamble\declareImageAndPlacement +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Embed Multi-page Images} +% +% \begin{macro}{\iconNameI} +% \cs{iconNameI} is the ``template name'' for the icons, this template is a JavaScript string and expands to a +% function of \texttt{i}. The default definition is given below. +% \begin{macrocode} +\newcommand{\iconNameI}[1]{\def\IconNameI(##1){#1}} +\iconNameI{#1+"."+i} +%\iconNameI{#1+i} +\@onlypreamble\iconNameI +% \end{macrocode} +% \begin{macro}{\embedMultiPageImages} +% \cs{embedMultiPageImages} is designed for a PDF filled with icon pages. It sets up a JavaScript +% loop, and imports the specified page range. The name of the icon is determined by +% the command \cs{iconNameI}, this is function of the JavaScript variable \texttt{i}, the index +% for the loop. The command embeds the icons only. The parameters are\dots +% \begin{itemize} +% \item[] key-value pairs: \texttt{firstpage}, \texttt{lastpage}, \texttt{placement}, +% \texttt{name} and \texttt{path} are the only keys recognized. +%\end{itemize} +% \begin{macrocode} +\newcommand{\embedMultiPageImages}[1]{% + \setkeys{importIcons}{name,path,page,placement,% + firstpage,lastpage,#1}% + \ifx\importIcons@firstpage\@empty + \def\importIcons@firstpage{1}\else + {\count0=\importIcons@firstpage}\fi + \ifx\importIcons@lastpage\@empty + \def\importIcons@lastpage{this.numPages}\else + {\count0=\importIcons@lastpage}\fi + \ifx\importIcons@name\@empty + \PackageError{aeb_pro}{The `name' key is required} + {Please give the icon family a name.}\fi + \ifx\importIcons@path\@empty + \PackageError{aeb_pro}{The `path' key is required} + {Please give the path of the icon.}\fi + \def\r{^^J}\def\t{\space\space\space\space}% + \let\predocassemJSPlace\@empty + \ifx\importIcons@placement\@empty\else + \@for\@fieldname:=\importIcons@placement\do{% + \expandafter\aebp@getFace\@fieldname\@nil + \edef\predocassemJSPlace{\predocassemJSPlace\t + var f = this.getField("\importIcons@fieldname."+i);\r\t + if ( f == null ) console.println("The field + \string\"\importIcons@fieldname."+i+"\string\" + does not exist.");\r\t + try { f.buttonSetIcon(this.getIcon(% +\IconNameI("\importIcons@name")),% + \importIcons@face); } + catch(e){};\r}% + }% + \fi + \xdef\predocassemJS{\predocassemJS + var l=\importIcons@lastpage-\importIcons@firstpage+1;\r + for (var i=0; i<l; i++) {\r\t + var retn=\importIcon({% + cName:\IconNameI("\importIcons@name"),% + cDIPath:"\importIcons@path",% + nPage:\importIcons@firstpage+i-1});\r\t + if ( retn==-1 ) console.println("The file + \string\"\importIcons@path\string\" could not + be opened.");\r\t + if ( retn==-2 ) console.println("Selected page + (page="+(i+1)+") for \string\"\importIcons@path\string\" + is invalid.");\r + \predocassemJSPlace + }\r + var oIcon=this.getIcon("nullIcon");\r + if ( oIcon == null ) + this.addIcon("nullIcon", this.createIcon("", 0, 0));\r + }% +} +\@onlypreamble\embedMultiPageImages +% End aebpro and createicon segments +%</aebpro|createicon> +%<*aebpro> +% \end{macrocode} +% \begin{macrocode} +% End aebpro segment +%</aebpro> +%<*animecommon> +% \end{macrocode} +% \begin{macro}{\placeAnimeCtrlBtnFaces} +% This command is part of the button anime set. It embeds (using the command \cs{declareMultiImages}) +% the icon appearances of the anime controls, The field names for these controls have a name +% of the form +%\begin{quote} +%\texttt{<anime\_basename>4BtnCtrl.<fieldName>} +%\end{quote} +% where \texttt{<anime\_basename>} is the +% base name of the field that displays the images; and \texttt{<fieldName>} is the name of +% the particular control. +% +% The first parameter is the relative or absolute path to the icons set (this path is +% used by Acrobat JavaScript, not by {\LaTeX}; the second parameter is a comma-delimited +% list of button animes to be controlled. An example follows: +%\begin{verbatim} +%\placeAnimeCtrlBtnFaces{graphics/btn_anime_icons1.pdf}% +% {myAnimation,mysine,FamPhotos} +%\end{verbatim} +% \begin{macrocode} +\newcommand{\placeAnimeCtrlBtnFaces}[3][\pathToBtnCtrlIcons]{\begingroup + \toks@={\aep@I{\aep@setAFirst}{animeFirst}% + \aep@I{\aep@setASB}{animeSB}% + \aep@I{\aep@setAPB}{animePB}% + \aep@I{\aep@setAPaus}{animePause}% + \aep@I{\aep@setAPF}{animePF}% + \aep@I{\aep@setASF}{animeSF}% + \aep@I{\aep@setALast}{animeLast}% + \aep@I{\aep@setAPlus}{animePlus}% + \aep@I{\aep@setAMinus}{animeMinus}}% + \def\aep@I##1##2{\let##1\@empty}\the\toks@ + \def\aep@I##1##2{\edef##1{##1,\aep@thisAnime4BtnCtrl.##2}}% + \@for\aep@thisAnime:=#3\do{\the\toks@}% + \def\aep@I##1##2{\edef##1{\expandafter\@gobble##1}}\the\toks@ + \ifx\pathToBtnCtrlIcons\@empty + \let\@pathsep\@empty\else\def\@pathsep{/}\fi + \declareMultiImages{% +% \end{macrocode} +% A document author may supply his own icon set, they must be placed in a +% PDF document in the expected order:\par +% \begin{center} +% \begin{tabular}{cl} +% Page & Icon\\\hline +% 0 & Go to first frame\\ +% 1 & Go to last frame\\ +% 2 & Step back one frame\\ +% 3 & Step forward one frame\\ +% 4 & Play backward\\ +% 5 & Play forward\\ +% 6 & Pause\\ +% 7 & Increase speed\\ +% 8 & Decrease speed +% \end{tabular} +% \end{center} +% \begin{macrocode} + {path=#1\@pathsep#2,page=0,placement={\aep@setAFirst}} + {path=#1\@pathsep#2,page=2,placement={\aep@setASB}} + {path=#1\@pathsep#2,page=4,placement={\aep@setAPB}} + {path=#1\@pathsep#2,page=6,placement={\aep@setAPaus}} + {path=#1\@pathsep#2,page=5,placement={\aep@setAPF}} + {path=#1\@pathsep#2,page=3,placement={\aep@setASF}} + {path=#1\@pathsep#2,page=1,placement={\aep@setALast}} + {path=#1\@pathsep#2,page=7,placement={\aep@setAPlus}} + {path=#1\@pathsep#2,page=8,placement={\aep@setAMinus}} + }% + \endgroup +} +\@onlypreamble\placeAnimeCtrlBtnFaces +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +% End animecommon segment +%</animecommon> +%<*aebpro> +% \end{macrocode} +% \begin{macrocode} +% \end{macrocode} +% \begin{macro}{\placeImageToBtn} +% \cs{iconNameI} is the ``template name'' for the icons, this template is a +% JavaScript string and expands to a function of \texttt{i}. The default +% definition is given below. +% \begin{macrocode} +\newcommand{\placeImageToBtn}[1]{% + \setkeys{importIcons}{name,path,page,placement,#1}% + \ifx\importIcons@placement\@empty\else + \@for\@fieldname:=\importIcons@placement\do{% + \expandafter\aebp@getFace\@fieldname\@nil + \xdef\predocassemJS{\predocassemJS + var f = this.getField("\importIcons@fieldname");^^J% + if ( f == null ) console.println("The field + \string\"\importIcons@fieldname\string\" + does not exist.");^^J% + try { f.buttonSetIcon(this.getIcon("\importIcons@name"),% + \importIcons@face); } + catch(e){};^^J}% + }% + \fi +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \subsubsection{\texorpdfstring{\cs{insertPreDocAssembly}}{\CMD{insertPreDocAssembly}}} +% \begin{macro}{\insertPreDocAssembly} +% This command is to be used within the \texttt{docassembly} environment, +% and expands to all the JavaScript lines created by +% \cs{declareImageAndPlacement}. +% \begin{macrocode} +% End aebpro segment +%</aebpro> +%<*aebpro|createicon> +\newcommand{\insertPreDocAssembly}{\predocassemJS} +\let\importAndSetImages\insertPreDocAssembly +% \end{macrocode} +% \end{macro} +% +% \subsection{Placing an Image (\texorpdfstring{\cs{placeImage}}{\CMD{placeImage}})} +% +% \begin{macro}{\placeImage} +% This command creates the target push buttons for the images imported using +% \cs{declareImageAndPlacement} and \cs{importAndSetImages}. It creates a readonly +% push button with an icon only appearance. The first argument can be used +% to modify the appearance (as described in the eforms manual), the second is +% the name of the field (this is referenced in the \texttt{placement} key of +% \cs{declareImageAndPlacement}, the third and fourth parameters are the width +% and height, respectively of the push button. +% \begin{macrocode} +\newcommand{\placeImage}[4][]{\pushButton[% + \BC{}\BG{}\S{S}\Ff{\FfReadOnly}\autoCenter{n}\FB{true} + #1\I{null}\TP{1}]{#2}{#3}{#4}} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +% End of aebpro and createicon segments +%</aebpro|createicon> +%<*animecommon> +% \end{macrocode} +% +% \subsection{Button and Ocg Animation (Anime)} +% +% The following are the key-value pairs common to both button and ocg anime. +% \begin{macro}{\animeSetup} +% \begin{macro}{\widthFirstRow} +% \cs{animeSetup} can be used to set the anime parameters when controls=none, and +% you want to move button set to a place other than the default location, which is +% below the anime. After setting the parameters, we have some code for calculating +% the \cs{widthFirstRow}. this value is used by \cs{insertCtrlButtons} to set the +% width of an enclosing \cs{parbox}, the first row is always wider than the second. +% \begin{macrocode} +\newcommand{\animeSetup}[1]{% + \let\animeSetupPresets\@empty + \edef\@tempExp{\noexpand\setkeys{btnAnime}{#1}}\@tempExp +% \setkeys{btnAnime}{#1}% + \ifx\btnAnimeCtrlBdryColor\@empty\else +% \end{macrocode} +% Calculate the presets for the buttons as passed by the key-values of +% \cs{animeSetup}. +% \begin{macrocode} + \edef\@tmpExp{\noexpand\g@addto@macro% + \noexpand\animeSetupPresets{% + \noexpand\BC{\btnAnimeCtrlBdryColor}}}\@tmpExp + \edef\@tmpExp{\noexpand\g@addto@macro% + \noexpand\animeSetupPresets{% + \noexpand\W{\btnAnimeCtrlBdryWidth}}}\@tmpExp\fi +% \end{macrocode} +% Calculate the value of \cs{@btnanimerowsep}, the distance between rows +% \begin{macrocode} + \edef\@btnanimerowsep{\btnanimerowsep}% dps10 +% \setlength{\@tempdima}{\btnanimerowsep+2bp}% +% \edef\@btnanimerowsep{\the\@tempdima}% +% \end{macrocode} +% Calculate the width of the widest row, usually the first. +% \begin{macrocode} + \setlength{\@tempdima}{% + (\btnAnimeCtrlW+2bp)*\numWidgetsFirstRow+% + (\btnanimebtnsep*(\numWidgetsFirstRow-1))}% + \addtolength{\@tempdima}{\addSpaceBtwnPMBtns}% + \edef\widthFirstRow{\the\@tempdima}% +} +% \end{macrocode} +% \begin{macro}{\insertCtrlButtons} +% This command can be used to place the anime controls somewhere other than at +% the default location (under the anime). +% \begin{macrocode} +\newcommand{\insertCtrlButtons}[1][c]{% + \parbox[#1][\totalheight+2bp]{\widthFirstRow}{% + \offinterlineskip\centering\aep@btn@anime@controls}} +\newcommand{\setspaceBtwnPMBtns}[1]{{% + \settowidth{\@tempdima}{#1\kern2bp}% + \xdef\tmp@spaceBtwnPMBtns{\the\@tempdima}}% + \edef\@spaceBtwnPMBtns{\tmp@spaceBtwnPMBtns}} +\setspaceBtwnPMBtns{\space} +\def\addSpaceBtwnPMBtns{\ifKV@btnAnime@usetworows0bp\else + \ifKV@btnAnime@nospeedcontrol0bp\else\@spaceBtwnPMBtns\fi\fi} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \paragraph{Define Key-value Pairs for anime.} The next set of code +% defines the key-value pairs for \cs{btnAnime} and \texttt{ocgAnime}.\IndexKey{type} +% \IndexKey{fieldName}\IndexKey{ocgAnimeName}\IndexKey{iconName}\IndexKey{speed}\par +% \IndexKey{nFrames} +% \begin{macrocode} +\define@choicekey+{btnAnime}{type}[\val\nr]% + {loop,palindrome,stopatboundary}[stopatboundary]{% + \edef\aebp@btnAnime@type{\nr}}{} +\define@key{btnAnime}{fieldName}[]{\gdef\animeBtnFieldName{#1}} +\define@key{btnAnime}{ocgAnimeName}[]{\gdef\animeBtnFieldName{#1}} +\define@key{btnAnime}{iconName}[]{\gdef\animeBtnBaseName{#1}} +\define@key{btnAnime}{speed}[200]{\gdef\animeBtnSpeed{#1}} +\define@key{btnAnime}{nFrames}[]{\gdef\nFrames{#1}} +% \end{macrocode} +% Additional keys +% \IndexKey{autorun}\IndexKey{autopause}\IndexKey{autoplayevent} +% \IndexKey{autopauseevent} +% \IndexKey{poster}% +% \begin{macrocode} +\define@boolkey{btnAnime}{autorun}[true]{} +\define@boolkey{btnAnime}{autopause}[true]{} +\define@choicekey+{btnAnime}{autoplayevent}[\val\nr]% + {pageopen,pagevisible}[pageopen]{\ifcase\nr\relax + \def\aebp@autoplayevent{\AAPageOpen}\or + \def\aebp@autoplayevent{\AAPageVisible}\fi}{}% +\def\aebp@autoplayevent{\AAPageOpen} +\define@choicekey+{btnAnime}{autopauseevent}[\val\nr]% + {pageclose,pageinvisible}[pageclose]{\ifcase\nr\relax + \def\aebp@autopauseevent{\AAPageClose}\or + \def\aebp@autopauseevent{\AAPageInvisible}\fi}{}% +\def\aebp@autopauseevent{\AAPageClose} +\define@choicekey+{btnAnime}{poster}[\val\nr]% + {first,last,none}[first]{\edef\aebp@btnAnime@poster{\nr}}{} +% \end{macrocode} +% (Needs FIX) Behavior of the poster. When \texttt{poster=first} this is OK, no bugs. +% When \texttt{poster=last} and the animation begins (at least for button) +% the animation does not appear to be running until the last frame, then +% it starts up. In this case, we display the last frame but when play is pressed +% the animation is `cleared' and begins from frame 1. +% \begin{macrocode} +% \end{macrocode} +% The following are key-values for the control buttons, in addition +% to \texttt{ctrlwidth}\IndexKey{ctrlwidth} and \texttt{ctrlheight}\IndexKey{ctrlheight}, +% we also include \texttt{ctrlbdrywidth}\IndexKey{ctrlbdrywidth} +% and \texttt{ctrlbdrycolor}\IndexKey{ctrlbdrycolor} the latter two so we can get the spacing +% correct. +% \begin{macrocode} +\define@key{btnAnime}{ctrlwidth}[18bp]{\def\btnAnimeCtrlW{#1}} +\define@key{btnAnime}{ctrlheight}[9bp]{\def\btnAnimeCtrlH{#1}} +\define@choicekey{btnAnime}{ctrlbdrywidth}[\val\nr]{none,% + thin,medium,thick}[thin]{\edef\btnAnimeCtrlBdryWidth{\nr}} +% \end{macrocode} +% (2017/03/08) Let \texttt{ctrlbdrycolor} accept \pkg{xcolor}, if loaded +% \changes{v2.8a}{2017/03/08}{\string\texttt{ctrlbdrycolor} accepts \string\pkg{xcolor}, if loaded} +% \begin{macrocode} +\define@key{btnAnime}{ctrlbdrycolor}[]{\def\ap@argi{#1}% + \ifx\ap@argi\@empty\let\btnAnimeCtrlBdryColor\@empty\else + \HyColor@IfXcolor{\HyColor@XZeroOneThreeFour{#1} + {\btnAnimeCtrlBdryColor}{}{}} + {\edef\btnAnimeCtrlBdryColor{#1}}\fi +} % PDF color +\let\animeSetupPresets\@empty +% \end{macrocode} +% A command to set the space between control buttons, uses \cs{btnanimebtnsep} +% \begin{macrocode} +\newcommand{\@ctrlsbtnsep}{\cgBdry[\btnanimebtnsep]} % dps10 +% \end{macrocode} +% \begin{macro}{\btnanimebtnsep} +% The space between buttons +% \begin{macro}{\vspacectrlsep} +% The vertical space between the bottom of the anime and the control button set. +% \begin{macro}{\btnanimerowsep} +% The vertical distance between two rows of control buttons. +% \begin{macrocode} +\newcommand{\btnanimebtnsep}{1bp} +\newcommand{\vspacectrlsep}{3bp} +\newcommand{\aep@vspacectrlsep}{\vspacectrlsep} +\newcommand{\btnanimerowsep}{1bp} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \paragraph{Definitions of ``skins'' may be redefined.} +% \begin{macro}{\btnAnimeSkini} +% \begin{macro}{\btnAnimeSkinii} +% \begin{macro}{\btnAnimeSkiniii} +% \begin{macro}{\btnAnimeSkiniv} +% \begin{macro}{\btnAnimeSkinv} +% \begin{macro}{\btnAnimeSkinvi} +% The definitions of the various control button layouts. These are normally +% not used by the document author. +% \begin{macrocode} +\newcommand{\btnAnimeSkini}{\ifKV@btnAnime@usetworows + \makebox[\linewidth][c]{% + \btnAnimeGoToFirst\@ctrlsbtnsep\btnAnimeStepBack + \@ctrlsbtnsep\btnAnimePlayBack + \@ctrlsbtnsep\btnAnimePause + \@ctrlsbtnsep\btnAnimePlayForward + \@ctrlsbtnsep\btnAnimeStepForward + \@ctrlsbtnsep\btnAnimeGoToLast}\ifKV@btnAnime@nospeedcontrol\else + \vcgBdry[\@btnanimerowsep]\makebox[\linewidth][c]{% + \btnAnimePlus\@ctrlsbtnsep\btnAnimeMinus}\fi\else + \makebox[\linewidth][s]{\hss + \btnAnimeGoToFirst + \@ctrlsbtnsep\btnAnimeStepBack + \@ctrlsbtnsep\btnAnimePlayBack + \@ctrlsbtnsep\btnAnimePause + \@ctrlsbtnsep\btnAnimePlayForward + \@ctrlsbtnsep\btnAnimeStepForward + \@ctrlsbtnsep\btnAnimeGoToLast + \ifKV@btnAnime@nospeedcontrol\else + \kern\@spaceBtwnPMBtns\btnAnimePlus + \@ctrlsbtnsep\btnAnimeMinus\fi\hss}\fi} +\newcommand{\btnAnimeSkinii}{\ifKV@btnAnime@usetworows + \makebox[\linewidth][c]{% + \btnAnimeGoToFirst + \@ctrlsbtnsep\btnAnimePlayBack + \@ctrlsbtnsep\btnAnimePause + \@ctrlsbtnsep\btnAnimePlayForward + \@ctrlsbtnsep\btnAnimeGoToLast}% + \ifKV@btnAnime@nospeedcontrol\else\vcgBdry[\@btnanimerowsep]% + \makebox[\linewidth][c]{\btnAnimePlus\@ctrlsbtnsep + \btnAnimeMinus}\fi\else\makebox[\linewidth][s]{\hss + \btnAnimeGoToFirst\@ctrlsbtnsep + \btnAnimePlayBack\@ctrlsbtnsep\btnAnimePause% + \@ctrlsbtnsep\btnAnimePlayForward\@ctrlsbtnsep + \btnAnimeGoToLast\ifKV@btnAnime@nospeedcontrol\else + \kern\@spaceBtwnPMBtns\btnAnimePlus + \@ctrlsbtnsep\btnAnimeMinus\fi\hss}\fi} +\newcommand{\btnAnimeSkiniii}{\ifKV@btnAnime@usetworows + \makebox[\linewidth][c]{% + \btnAnimeGoToFirst\@ctrlsbtnsep\btnAnimePause + \@ctrlsbtnsep\btnAnimePlayForward}% + \ifKV@btnAnime@nospeedcontrol\else + \vcgBdry[\@btnanimerowsep]\makebox[\linewidth][c]{% + \btnAnimePlus\@ctrlsbtnsep\btnAnimeMinus}\fi\else + \makebox[\linewidth][s]{\hss + \btnAnimeGoToFirst\@ctrlsbtnsep\btnAnimePause + \@ctrlsbtnsep\btnAnimePlayForward + \ifKV@btnAnime@nospeedcontrol\else\kern\@spaceBtwnPMBtns + \btnAnimePlus\@ctrlsbtnsep\btnAnimeMinus\fi\hss}\fi} +\newcommand{\btnAnimeSkiniv}{% + \makebox[\linewidth][c]{% + \btnAnimeGoToFirst + \@ctrlsbtnsep\btnAnimeStepBack + \@ctrlsbtnsep\btnAnimeStepForward + \@ctrlsbtnsep\btnAnimeGoToLast}} +\newcommand{\btnAnimeSkinv}{\PackageWarning{aeb_pro} + {skin5 is undefined.\MessageBreak You may customize + by defining skin5;\MessageBreak meanwhile, using default, + skin1}\btnAnimeSkini} +\newcommand{\btnAnimeSkinvi}{\PackageWarning{aeb_pro} + {skin6 is undefined.\MessageBreak You may customize + by defining skin6;\MessageBreak meanwhile, using default, + skin1}\btnAnimeSkini} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% The choice for the \texttt{controls}\IndexKey{controls} key. \texttt{skin5} and \texttt{skin6} +% default to \texttt{skin1}. These can be redefined for a custom configuration. +% \begin{macrocode} +\newcommand{\aepnumWidgetsFirstRow}[2]{\def\numWidgetsFirstRow{% + \ifKV@btnAnime@nospeedcontrol#1\else + \ifKV@btnAnime@usetworows#1\else#2\fi\fi}} +\newcommand{\numWidgetsFirstRowV}{\aepnumWidgetsFirstRow{7}{9}} +\newcommand{\numWidgetsFirstRowVI}{\aepnumWidgetsFirstRow{7}{9}} +\define@choicekey+{btnAnime}{controls}[\val\nr]% + {none,skin1,skin2,skin3,skin4,skin5,skin6}[skin1]{% + \ifcase\nr\relax + \let\aep@btn@anime@controls\@empty + \def\widthFirstRow{0pt}\or + \def\aep@btn@anime@controls{\btnAnimeSkini}% + \aepnumWidgetsFirstRow{7}{9}\or + \def\aep@btn@anime@controls{\btnAnimeSkinii}% + \aepnumWidgetsFirstRow{5}{7}\or + \def\aep@btn@anime@controls{\btnAnimeSkiniii}% + \aepnumWidgetsFirstRow{3}{5}\or + \def\aep@btn@anime@controls{\btnAnimeSkiniv}% + \aepnumWidgetsFirstRow{4}{4}\or + \def\aep@btn@anime@controls{\btnAnimeSkinv}% + \numWidgetsFirstRowV\or + \def\aep@btn@anime@controls{\btnAnimeSkinvi}% + \numWidgetsFirstRowVI\fi + }{} +% \end{macrocode} +% The \texttt{usetworows}\IndexKey{usetworows} and +% \texttt{nospeedcontrol}\IndexKey{nospeedcontrol} key +% \begin{macrocode} +\define@boolkey{btnAnime}{usetworows}[true]{} +\define@boolkey{btnAnime}{nospeedcontrol}[true]{} +% \end{macrocode} +% Set the defaults for button animation. +% \begin{macrocode} +\setkeys{btnAnime}{fieldName,iconName,speed,nFrames,type,poster, + controls,usetworows=false,nospeedcontrol=false,ctrlwidth,ctrlheight, + ctrlbdrywidth,ctrlbdrycolor} +% \end{macrocode} +% \begin{macrocode} +\newcommand{\btnAnimePresets}[1]{\def\aeb@btnAnimePresets{#1}} +\def\aeb@btnAnimePresets{} +% \end{macrocode} +% \begin{macro}{\ctrlButtonsWrapper} +% The \cs{ctrlButtonsWrapper} command takes one argument, and that is +% \cs{in\-sert\-Ctrl\-But\-tons}. Redefine this command to, for example, place +% a \cs{colorbox} around the button set, +%\begin{verbatim} +% \renewcommand\ctrlButtonsWrapper}[1]{\colorbox{red}{#1}} +%\end{verbatim} +% The default definition is\dots +% \begin{macrocode} +\newcommand{\ctrlButtonsWrapper}[1]{#1} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +% End animecommon segment +%</animecommon> +%<*btnanime> +% \end{macrocode} +% \subsubsection{Define \texorpdfstring{\cs{btnAnime}}{\CMD{btnAnime}}} +% \begin{macro}{\btnAnime} +% The command \cs{btnAnime} supplies basic animation support using buttons. +% The command \cs{btnAnime} assumes the images are embedded in the document using +% \cs{embedMultiPageImages}, icon images for the controls are supplied by +% \cs{placeAnimeCtrlBtnFaces}. +% \begin{macrocode} +\newcommand{\btnAnime}[3]{\begingroup\animeSetup{#1}% + \ifx\animeBtnFieldName\@empty\PackageError{aeb_pro}% + {The fieldName key is required}{}\fi + \ifx\animeBtnBaseName\@empty\PackageError{aeb_pro}% + {The iconName key is required}{}\fi + \ifx\nFrames\@empty\PackageError{aeb_pro}% + {The nFrames key is required}{}\fi + \parbox[t][#3]{#2}{% +% \end{macrocode} +% Set the properties of the pushbutton to be created. +% \begin{macrocode} + \everyPushButton{\BC{}\BG{}\S{S}\autoCenter{n}\FB{true}\TP{1}% + \Ff{\FfReadOnly}\presets{\aeb@btnAnimePresets}\I{null}}% +% \end{macrocode} +% Set the options for the first frame, it is either visible if \texttt{poster=first} +% or hidden, otherwise. +% \begin{macrocode} + \edef\termLoop{\nFrames}\edef\firstBtnOpts{% + \ifnum\aebp@btnAnime@poster=0 \else\noexpand\F{\FHidden}\fi + \noexpand\AA{\ifKV@btnAnime@autorun + \aebp@autoplayevent{\noexpand\btnAnimePFAction}\fi + \ifKV@btnAnime@autopause + \aebp@autopauseevent{\noexpand\btnAnimePauseAction}\fi}}% +% \end{macrocode} +% Begin with the first button. +% \begin{macrocode} + \makebox[0pt][l]{\expandafter\pushButton + \expandafter[\firstBtnOpts]{\animeBtnFieldName.0}{#2}{#3}}% +% \end{macrocode} +% If \texttt{poster=last}, decrement \cs{termLoop} by one. +% \begin{macrocode} + \ifnum\aebp@btnAnime@poster=1 + \count0=\nFrames\relax\advance\count0by-1 + \edef\termLoop{\the\count0}\fi\@tempcnta=1 +% \end{macrocode} +% Begin to `stack' the buttons (first button already in place) +% \begin{macrocode} + \loop\ifnum\@tempcnta<\termLoop\relax + \makebox[0pt][l]{\pushButton[\F{\FHidden}]{% + \animeBtnFieldName.\the\@tempcnta}{#2}{#3}}% + \advance\@tempcnta1\relax\repeat +% \end{macrocode} +% Finished with the look, if \texttt{poster=last}, then we did not stack +% the last button, we do it now. +% \begin{macrocode} + \ifnum\aebp@btnAnime@poster=1\relax\makebox[0pt][l]{% + \pushButton{\animeBtnFieldName.\termLoop}{#2}{#3}}% + \fi\hfill\ifx\aep@btn@anime@controls\@empty\else + \offinterlineskip\vcgBdry[\vspacectrlsep]% +% \end{macrocode} +% Now build the control buttons +% \begin{macrocode} + \everyPushButton{}\centering + \ctrlButtonsWrapper{\insertCtrlButtons}\fi + }%parbox + \endgroup +} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +% End btnanime segment +%</btnanime> +%<*ocganime> +% \end{macrocode} +% \subsubsection{Define \texttt{ocgAnime}} +% \begin{environment}{ocgAnime} +% We upgrade the ocg animation to the same level of button animation. We define the +% \texttt{ocgAnime} environment. Between he \verb!\begin{ocgAnime}! and \verb!\end{ocgAnime}!, +% place the code for creating the animation. The only required parameters consist of the same +% key-value pairs accepted by \cs{btnAnime}. Some keys are not used, such as \texttt{iconName}. +% The fields \texttt{ocgAnimeName} and \texttt{nFrames} are required. +% \begin{macrocode} +\newenvironment{ocgAnime}[1]{\animeSetup{#1}% + \ifx\animeBtnFieldName\@empty\PackageError{aeb_pro}% + {The ocgAnimeName key is required}{}\fi + \ifx\nFrames\@empty\PackageError{aeb_pro}% + {The nFrames key is required}{}\fi + \DeclareAnime{\animeBtnFieldName}{\animeBtnSpeed}{\nFrames}% +}{% + \edef\aep@ExpOpts{\noexpand\AA{\ifKV@btnAnime@autorun + \aebp@autoplayevent{\noexpand\btnAnimePFAction}\fi + \ifKV@btnAnime@autopause\aebp@autopauseevent{% + \noexpand\btnAnimePauseAction}\fi}}\smash{\makebox[0pt][l]% + {\expandafter\pushButton\expandafter[\aep@ExpOpts\W0\BC{}\BG{}\S{S}]% + {\animeBtnFieldName-autorunpause}{0bp}{0bp}}}% + \ifx\aep@btn@anime@controls\@empty\else\offinterlineskip + \vcgBdry[\vspacectrlsep]\everyPushButton{}% + \centering\ctrlButtonsWrapper{\insertCtrlButtons}\fi +} +% \end{macrocode} +% \end{environment} +% \begin{macrocode} +% End of ocganime segment +%</ocganime> +%<*animecommon> +% \end{macrocode} +% \begin{macro}{\btnAnimeCtrlPresets} +% Use \cs{btnAnimeCtrlPresets} to set the appearances for all these buttons below. +% \begin{macro}{\btnAnimeGoToFirst} +% \begin{macro}{\btnAnimeStepBack} +% \begin{macro}{\btnAnimePlayBack} +% \begin{macro}{\btnAnimePause} +% \begin{macro}{\btnAnimePlayForward} +% \begin{macro}{\btnAnimeStepForward} +% \begin{macro}{\btnAnimeGoToLast} +% \begin{macro}{\btnAnimePlus} +% \begin{macro}{\btnAnimeMinus} +% The control buttons for button anime. These commands are not normally used by +% the document author, but can be used for a custom layout. +% \begin{macrocode} +\newcommand{\btnAnimeCtrlPresets}[1]{\def\aeb@btnAnimeCtrlPresets{#1}} +\def\aeb@btnAnimeCtrlPresets{} +\newcommand{\btnAnimeGoToFirst}{% + \pushButton[\TU{Go to first frame}\S{S}\BC{} + \FB{false}\I{null}\TP{1}\presets{\aeb@btnAnimeCtrlPresets} + \presets{\animeSetupPresets}\A{\JS{\btnAnimeFirstAction}}]% + {\animeBtnFieldName4BtnCtrl.animeFirst}% + {\btnAnimeCtrlW}{\btnAnimeCtrlH}}% +\newcommand{\btnAnimeStepBack}{% + \pushButton[\TU{Step Back}\S{S}\BC{} + \FB{false}\I{null}\TP{1}\presets{\aeb@btnAnimeCtrlPresets} + \presets{\animeSetupPresets}\A{\JS{\btnAnimeSBAction}}]% + {\animeBtnFieldName4BtnCtrl.animeSB}% + {\btnAnimeCtrlW}{\btnAnimeCtrlH}} +\newcommand{\btnAnimePlayBack}{% + \pushButton[\TU{Play Backwards}\S{S}\BC{} + \FB{false}\I{null}\TP{1}\presets{\aeb@btnAnimeCtrlPresets} + \presets{\animeSetupPresets}\A{\JS{\btnAnimePBAction}}]% + {\animeBtnFieldName4BtnCtrl.animePB}% + {\btnAnimeCtrlW}{\btnAnimeCtrlH}} +\newcommand{\btnAnimePause}{% + \pushButton[\TU{Pause}\S{S}\BC{} + \FB{false}\I{null}\TP{1}\presets{\aeb@btnAnimeCtrlPresets} + \presets{\animeSetupPresets}\A{\JS{\btnAnimePauseAction}}]% + {\animeBtnFieldName4BtnCtrl.animePause}% + {\btnAnimeCtrlW}{\btnAnimeCtrlH}} +\newcommand{\btnAnimePlayForward}{% + \pushButton[\TU{Play Forwards}\S{S}\BC{} + \FB{false}\I{null}\TP{1}\presets{\aeb@btnAnimeCtrlPresets} + \presets{\animeSetupPresets}\A{\JS{\btnAnimePFAction}}]% + {\animeBtnFieldName4BtnCtrl.animePF}% + {\btnAnimeCtrlW}{\btnAnimeCtrlH}} +\newcommand{\btnAnimeStepForward}{% + \pushButton[\TU{Step Forward}\S{S}\BC{} + \FB{false}\I{null}\TP{1}\presets{\aeb@btnAnimeCtrlPresets} + \presets{\animeSetupPresets}\A{\JS{\btnAnimeSFAction}}]% + {\animeBtnFieldName4BtnCtrl.animeSF}% + {\btnAnimeCtrlW}{\btnAnimeCtrlH}} +\newcommand{\btnAnimeGoToLast}{% + \pushButton[\TU{Go to last frame}\S{S}\BC{} + \FB{false}\I{null}\TP{1}\presets{\aeb@btnAnimeCtrlPresets} + \presets{\animeSetupPresets}\A{\JS{\btnAnimeLastAction}}]% + {\animeBtnFieldName4BtnCtrl.animeLast}% + {\btnAnimeCtrlW}{\btnAnimeCtrlH}} +% These last two do not take an icon. +\newcommand{\btnAnimePlus}{% + \pushButton[\TU{Increase speed\r Shift-click to restore + default speed}%\textFont{HeBo}\CA{+} + \S{S}\BC{}\FB{false}\I{null}\TP{1} + \presets{\aeb@btnAnimeCtrlPresets} + \presets{\animeSetupPresets}\A{\JS{\btnAnimePlusAction}}]% + {\animeBtnFieldName4BtnCtrl.animePlus}% + {\btnAnimeCtrlW}{\btnAnimeCtrlH}} +\newcommand{\btnAnimeMinus}{% + \pushButton[\TU{Decrease speed\r Shift-click to restore + default speed}%\textFont{HeBo}\uCA{FEFF2212} + \S{S}\BC{}\FB{false}\I{null}\TP{1} + \presets{\aeb@btnAnimeCtrlPresets} + \presets{\animeSetupPresets}\A{\JS{\btnAnimeMinusAction}}]% + {\animeBtnFieldName4BtnCtrl.animeMinus}% + {\btnAnimeCtrlW}{\btnAnimeCtrlH}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% The following are the field events for the controls for \cs{btnAnime} +% and \texttt{acgAnime}. +% \begin{macrocode} +\newcommand{\btnAnimeFirstAction}{% +if (typeof \animeBtnFieldName\space == "object")\r\t + btnAnimeFirst(\animeBtnFieldName); +} +\newcommand{\btnAnimeSBAction}{% + if ( typeof \animeBtnFieldName\space=="undefined")\r\t + var \animeBtnFieldName= new Object();\r + btnAnimePlay(\animeBtnFieldName,"\animeBtnFieldName",% + "\animeBtnBaseName",\animeBtnSpeed,\nFrames,false,% + \aebp@btnAnime@type,true); +} +\newcommand{\btnAnimePBAction}{% + if ( typeof \animeBtnFieldName\space=="undefined")\r\t + var \animeBtnFieldName= new Object();\r + btnAnimePlay(\animeBtnFieldName,"\animeBtnFieldName",% + "\animeBtnBaseName",\animeBtnSpeed,\nFrames,false,% + \aebp@btnAnime@type,false); +} +\newcommand{\btnAnimePauseAction}{% + if ((typeof \animeBtnFieldName\space == "object")&&% + \animeBtnFieldName.animeStart)\r\t + btnAnimePause(\animeBtnFieldName); +} +\newcommand{\btnAnimePFAction}{% + if ( typeof \animeBtnFieldName\space=="undefined")\r\t + var \animeBtnFieldName= new Object();\r + btnAnimePlay(\animeBtnFieldName,"\animeBtnFieldName",% + "\animeBtnBaseName",\animeBtnSpeed,\nFrames,true,% + \aebp@btnAnime@type,false); +} +\newcommand{\btnAnimeSFAction}{% + if ( typeof \animeBtnFieldName\space=="undefined")\r\t + var \animeBtnFieldName= new Object();\r + btnAnimePlay(\animeBtnFieldName,"\animeBtnFieldName",% + "\animeBtnBaseName",\animeBtnSpeed,\nFrames,true,% + \aebp@btnAnime@type,true); +} +\newcommand{\btnAnimeLastAction}{% + if (typeof \animeBtnFieldName\space == "object")\r\t + btnAnimeLast(\animeBtnFieldName); +} +\newcommand{\btnAnimePlusAction}{% + if (typeof \animeBtnFieldName\space == "object")\r\t + btnAnimePlus(\animeBtnFieldName,\animeBtnSpeed); +} +\newcommand{\btnAnimeMinusAction}{% + if (typeof \animeBtnFieldName\space == "object")\r\t + btnAnimeMinus(\animeBtnFieldName,\animeBtnSpeed); +} +% \end{macrocode} +% The supporting JavaScript. This set of JavaScript functions support both button anime and +% ocg anime (the \cs{btnAnime} command and the \texttt{ocgAnime} environment). +% \begin{macrocode} +\begin{insDLJS}[_loadBtnAnimeCtrls]{btnanime} + {AeB Pro: Button and Ocg Anime Controls} +var _loadBtnAnimeCtrls=true; +var activeAnimes=new Array(); +% \end{macrocode} +% This function may be called with a single argument \texttt{oAnime} +% when the anime is playing. +% \begin{macrocode} +function btnAnimePlay(oAnime,fieldName,baseFrameName,% +nSpeed,nFrames,bForward,type,bStep) { + // ocgAnime is characterized by baseFrameName="" + if ( oAnime.animeStart && !oAnime.animePause ) return; + var callingFieldName=event.target.name; + var re=/\.anime(PB|PF)/; + var doRebuild=( event.shift && re.test(callingFieldName) ); + if ( (arguments.length>1) && % +( (typeof activeAnimes[fieldName] == "undefined")|| doRebuild) ) { + activeAnimes[fieldName]=oAnime; + oAnime.isOcgAnime=(baseFrameName==""); // ocg change + oAnime.fieldName=fieldName; + oAnime.baseFrameName=baseFrameName; + oAnime.numSecs=nSpeed; + oAnime.nFrames=nFrames; + oAnime.type=type; + oAnime.bStep=bStep; + oAnime.aMyIcons = new Array(); + oAnime.count = 0; + if ( !oAnime.isOcgAnime ) {// ocg change + for ( var i=0; i < nFrames; i++) { + oAnime.aMyIcons[i] = this.getField(fieldName+"."+i); +% \end{macrocode} +% (2015/08/09) When starting for the first time, be sure initial frame +% showing is the first frame 0. +% \begin{macrocode} + oAnime.aMyIcons[i].display=(i==0)?display.visible:% +display.hidden; + } + } + } + if (arguments.length>1) { + oAnime.bForward=bForward; + oAnime.bStep=bStep; + } +% \end{macrocode} +% \texttt{type}: \texttt{loop}(0), \texttt{palindrome}(1), \texttt{stopatboundary}(2) +% \begin{macrocode} + if (oAnime.bStep) { + this.delay=true + if ( oAnime.isOcgAnime ) // ocg change + getxBld("anime!!"+oAnime.fieldName+"\#"% ++(oAnime.count+1)).state=false; // ocg + else + oAnime.aMyIcons[oAnime.count].display=display.hidden; + var currCount=oAnime.count; + if (oAnime.bForward) { + oAnime.count++; + if (oAnime.count==oAnime.nFrames) // hit upper boundary + oAnime.count=(oAnime.type==0)?0:currCount; + } else { + oAnime.count--; + if (oAnime.count<0) + oAnime.count=(oAnime.type==0)?(oAnime.nFrames-1):0; + } + if ( oAnime.isOcgAnime ) // ocg change + getxBld("anime!!"+oAnime.fieldName+"\#"% ++(oAnime.count+1)).state=true; // ocg + else + oAnime.aMyIcons[oAnime.count].display=display.visible; + this.delay=false; + } else { + var args="\""+oAnime.fieldName+"\","+oAnime.type; + oAnime.run = app.setInterval(% +"btnAnimeNewFrame("+args+")",oAnime.numSecs); + oAnime.animeStart=true; + oAnime.animePause=false; + } +} +function btnAnimeFirst(oAnime) +{ + try { app.clearInterval(oAnime.run);} catch(e){} + oAnime.animeStart=false; + oAnime.animePause=false; + if ( oAnime.isOcgAnime ) + getxBld("anime!!"+oAnime.fieldName+"\#"% ++(oAnime.count+1)).state=false; // ocg + else + oAnime.aMyIcons[oAnime.count].display=display.hidden; + oAnime.count=0; + if ( oAnime.isOcgAnime ) + getxBld("anime!!"+oAnime.fieldName+"\#"% ++(oAnime.count+1)).state=true; // ocg + else + oAnime.aMyIcons[0].display=display.visible; +} +function btnAnimeLast(oAnime) +{ + try { app.clearInterval(oAnime.run);} catch(e){} + oAnime.animeStart=false; + oAnime.animePause=false; + var l = oAnime.nFrames-1; + if ( oAnime.isOcgAnime ) + getxBld("anime!!"+oAnime.fieldName+"\#"% ++(oAnime.count+1)).state=false; // ocg + else + oAnime.aMyIcons[oAnime.count].display=display.hidden; + oAnime.count=l; + if ( oAnime.isOcgAnime ) + getxBld("anime!!"+oAnime.fieldName+"\#"% ++(l+1)).state=true; // ocg + else + oAnime.aMyIcons[l].display=display.visible; +} +function btnAnimePause(oAnime) +{ + try { app.clearInterval(oAnime.run);} catch(e){} + oAnime.animePause=true; +} +function btnAnimePlus(oAnime,nDefSpeed){ + var isPlaying=(oAnime.animeStart&&!oAnime.animePause); + if (isPlaying) btnAnimePause(oAnime); + if ( event.shift ) oAnime.numSecs=nDefSpeed; + else oAnime.numSecs -= 50; + if (oAnime.numSecs<10) oAnime.numSecs=10 + if (isPlaying) btnAnimePlay(oAnime); +} +function btnAnimeMinus(oAnime,nDefSpeed){ + var isPlaying=(oAnime.animeStart&&!oAnime.animePause); + if (isPlaying) btnAnimePause(oAnime); + if ( event.shift ) oAnime.numSecs=nDefSpeed; + else oAnime.numSecs += 50; + if (isPlaying) btnAnimePlay(oAnime); +} +function btnAnimeNewFrame(fieldName, type) +{ +% \end{macrocode} +% \texttt{type=0,2,3}: \texttt{loop}(0), \texttt{palindrome}(1), \texttt{stopatboundary}(2) +% \begin{macrocode} + var oAnime=activeAnimes[fieldName]; + this.delay=true + if ( oAnime.isOcgAnime ) // ocg change + getxBld("anime!!"+oAnime.fieldName+"\#"% ++(oAnime.count+1)).state=false; + else + oAnime.aMyIcons[oAnime.count].display=display.hidden; + var currCount=oAnime.count; + var bBdaryMet=false; + if (oAnime.bForward) { + oAnime.count++; + if (oAnime.count==oAnime.nFrames) { + if(type==0) oAnime.count \%= oAnime.nFrames; + else if(type==1) { + oAnime.count=currCount; + oAnime.count--; + oAnime.bForward=false; + } else { + bBdaryMet=true; + oAnime.count=currCount; + } + } + } else { + oAnime.count--; + if (oAnime.count<0) { + if(type==0) oAnime.count=(oAnime.nFrames-1); + else if(type==1) { + oAnime.count=currCount; + oAnime.count++; + oAnime.bForward=true; + } else { // stop + bBdaryMet=true; + oAnime.count=currCount; + } + } + } + if ( oAnime.isOcgAnime) // ocg change + getxBld("anime!!"+oAnime.fieldName+"\#"% ++(oAnime.count+1)).state=true; + else + oAnime.aMyIcons[oAnime.count].display=display.visible; + this.delay=false; + if ( type==2 && bBdaryMet ) { + try { app.clearInterval(oAnime.run);} catch(e){} + // try { app.clearTimeOut(timeout);} catch(e){} + oAnime.animeStart=false; + oAnime.animePause=false; + } +} +\end{insDLJS} +% \end{macrocode} +% \begin{macrocode} +% End of animecommon segment +%</animecommon> +% \end{macrocode} +% \begin{macrocode} +% Begin package segment +%<*package> +\ap@restoreCats +%</package> +% \end{macrocode} +% \Finale +\endinput |