% \iffalse %<*copyright> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% InsDLJS.sty package, 2002-2-2 %% %% Copyright (C) 2001-2002 D. P. Story %% %% dpstory@uakron.edu %% %% %% %% This program can redistributed and/or modified under %% %% the terms of the LaTeX Project Public License %% %% Distributed from CTAN archives in directory %% %% macros/latex/base/lppl.txt; either version 1 of the %% %% License, or (at your option) any later version. %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{insdljs} % [2001/09/26 v2.0c Insert Document-Level JavaScripts (dps)] %<*driver> \documentclass{ltxdoc} \usepackage[colorlinks,hyperindex]{hyperref} \pdfstringdefDisableCommands{\let\\\textbackslash}% \EnableCrossrefs \CodelineIndex \begin{document} \GetFileInfo{insdljs.sty} \title{The \texttt{insDLJS} Package} \author{D. P. Story\\ Email: \texttt{dpstory@uakron.edu}} \date{processed \today} \maketitle \tableofcontents \let\Email\texttt \DocInput{insdljs.dtx} \PrintIndex \end{document} % % \fi % \section{Introduction} % This package defines a new environment, \texttt{insDLJS}, used % for inserting Acrobat JavaScript into a PDF file created from a % \LaTeX{} source. This package works correctly for users of % \textsf{pdftex} or \textsf{dvipdfm}. For those that use the % \textsf{Acrobat Distiller} (specifically, those that use either % \textsf{dvips} or \textsf{dvipsone} to produce a postscript file, % which is then distilled), you are required to have Acrobat~5.0 (or % later). % % \subsection{The \texttt{insDLJS} Environment} % % The following is a quick illustration of the use of the new environment. % \begin{verbatim} % \documentclass{article} % \usepackage[pdftex]{hyperref} % \usepackage[pdftex]{insdljs} % % \newcommand\tugHello{Welcome to TUG 2001!} % % \begin{insDLJS}[HelloWorld]{mydljs}{My Private DLJS} % function HelloWorld() % { % app.alert("\tugHello", 3); % } % \end{insDLJS} % \begin{document} % \begin{Form} % needed for \PushButton % % \section{Test of the \texttt{insDLJS} Package} % % % use built in form button of hyperref % Push \PushButton[name=myButton, % onclick={HelloWorld();}]{Button} % % \end{Form} % \end{document} % \end{verbatim} % This environment takes three parameters, the first of which is required % for users of \texttt{dvips} and \texttt{dvipsone} and optional otherwise. % Within the environment, `|\|', is the escape character, and `|%|' is the comment % character, as they are in \TeX{} and \LaTeX. % See the documentation preceding the definition of the % \texttt{\hyperlink{insDLJS}{insDLJS}} environment. % % There is a complication with writing JavaScript and \TeX{} together: they both use % the backslash character, `|\|', as the escape character. % In JavaScript, certain characters have special meaning: % Backspace (\texttt{\string\b}), form feed (\texttt{\string\f}), % New line (\texttt{\string\n}), Carriage return (\texttt{\string\r}), % Tab (\texttt{\string\t}), Vertical tab (\texttt{\string\v}), Apostrophe or % single quote (\texttt{\string\'}), Double quote (\texttt{\string\"}). % Within a regular expression, these characters have special meaning, and must % be escaped to get their literal meaning: % Forward slash (`\texttt/'), Backward slash (`\verb+\+'), Period (`\texttt.'), % Asterisk (`\texttt*'), Plus (`\texttt+'), Question Mark (`\texttt?'), Vertical Bar % (`\verb+|+'), Left Parenthesis (`\texttt{(}'), Right Parenthesis (`\texttt{)}'), % Left Bracket (`\texttt['), Right Bracket (`\texttt]'), Left curly brace (`\verb+{+'), % Right curly brace (`\verb+}+'). , E.g., for Asterisk (\texttt*), type % `\texttt{\string\*}' % % Complications continued. The distiller method (the \texttt{dvipsone} or the % \texttt{dvips} option), and the \textsf{pdftex}/\textsf{dvipdfm} applications % handle the backslash differently. The following example illustrates the problem. % {\small %\begin{verbatim} %dvipsone/dvips %LaTeX Source As appears in PDF %var x = "\"; --> var x = "\"; (SyntaxError: Unterminated string literal) %var x = "\\"; --> var x = "\\"; (Correct) %\end{verbatim}} % When we type \texttt{"\string\"}, we are beginning a string (with the first % double quotes, but then we have a literal \texttt{\string\"}, so we have not % closed the opening string, hence the error message. We have to type % `\verb+\\+' to get the single backslash. % {\small %\begin{verbatim} %pdftex/dvipdfm %LaTeX Source As appears in PDF %var x = "\"; --> var x = ""; (\" is the literal ") %var x = "\\"; --> var x = "\"; (SyntaxError: Unterminated string literal) %var x = "\\\\"; --> var x = "\\"; (Correct) %\end{verbatim}} % These applications write raw PDF code to the \texttt{.pdf} file. % All special characters need to be escaped. You can see, that \textsf{pdftex} % and \textsf{dvipdfm} require extra backslashs. % % The solution to this problem---the problem of how distiller and the two applications % handle backslashes---is to define control sequences for all the sequences JavaScript uses % and to adjust their definitions depending on the driver option. As a result, of these % background definitions, the JavaScript writer does not worry too much about these details, % for example %\begin{verbatim} %\begin{insDLJS}[HelloWorld]{mydljs}{My Private DLJS} %function HelloWorld() %{ % app.alert("\tugHello", 3); % var x = "\\"; % app.alert("x = " + x); %} %\end{insDLJS} %\end{verbatim} % So much for the complication. % % Another feature of this package is the ability to place debugging markers % within the JavaScript. When the \texttt{debug} option is used, the markers % show up in the document-level JavaScript; otherwise, they are not written % to the PDF document. Here is a simple example, % \begin{verbatim} %\begin{insDLJS}[HelloWorld]{mydljs}{My Private DLJS} %function HelloWorld() %{ % app.alert("\tugHello", 3); % var x = "\\"; %\db console.println("Entered HelloWorld function and x = " + x);\db% %} %\end{insDLJS} %\end{verbatim} % The last line of the function will appear in the DLJS if compiled under % the \texttt{debug} option; otherwise, it is removed. Additional discussion % of this debugging device is given below. % % \subsection{Open Action} % % This package also defines an \cs{OpenAction} command to introduce actions that are % executed when the PDF document is opened on page~1. The open action command only % applies to page~1. % \begin{flushleft} % \textbf{Usage} %\begin{verbatim} %\OpenAction{/S /JavaScript /JS(app.alert("Hello World!");)} %\end{verbatim} % \end{flushleft} % % Multiple JavaScript commands can be entered. For nice formatting use \cs{r} % and \cs{t} for carriage return and tab, respectively. %\begin{verbatim} %\OpenAction{/S /JavaScript /JS % (app.alert("Hello World!");\r % app.alert("Good Day to You!"); %)} %\end{verbatim} % The open actions are placed in a token list. Additional actions are added to the token list, so % you say %\begin{verbatim} %\OpenAction{/S /JavaScript /JS(app.alert("Hello World!");)} %\OpenAction{/S /JavaScript /JS(app.alert("Good Day to You!");)} %\end{verbatim} % the two messages will appear each time you open page~1 of the document. % % In the case of users of the distiller, \textsf{insdljs} uses this mechanism to % define an open action. To avoid overwriting this definition, the \cs{OpenAction} % command is necessary in insert additional actions. % % See \Nameref{openaction} for more detainls. % % \subsection{How \textsf{insdljs} Works} % % Let me describe in rough terms what goes on behind the scenes. In the discussion % below, the following example will be used: %\begin{verbatim} %\newcommand\tugHello{"Hello World!"} %\begin{insDLJS}[HelloWorld]{mydljs}{My Private DLJS} %function HelloWorld() %{ % app.alert("\tugHello", 3); %} %\end{insDLJS} %\end{verbatim} % % \subsubsection*{For the \texttt{pdftex} and \texttt{dvipdfm} Options} % % Both \texttt{pdftex} and \texttt{dvipdfm} have primitives/macros for inserting % JavaScript at the document level into the PDF document. The work of the package, % in this case, is to take the JavaScript and place it into the correct form % for the application (\textsf{pdftex} or \textsf{dvipdfm}). % % Material within the \texttt{insDLJS} environment is written verbatim to a file. % The name of this file is \texttt{mydljs.djs}. The file basename comes from the % first required parameter of the \texttt{insDLJS} environment, see example above. % The file extension \texttt{.djs} stands for ``define javascript''. % % At begin document, the file \texttt{mydljs.djs} is input back into the document after % special definitions have already been read. These special definitions are the content % of the file \texttt{dljscc.def}. The script is placed in the appropriate construct % for insertion by the application at the document level. % % For more information about \texttt{dljscc.def}, see documentation given in the Section~\ref*{dljscc}, % \Nameref{dljscc}. % % \subsubsection*{For the \texttt{dvipsone} and \texttt{dvips} Options} % % When you use the \texttt{dvipsone} or \texttt{dvips}, this means you are going to convert % your document to postscript and distill it to create a PDF document. There is no \texttt{pdfmark} % construct for inserting document level JavaScripts; however, the recent release of Acrobat~5.0 % gives postscript users an avenue for inserting DLJS. % % The material within the \texttt{insDLJS} environment is written verbatim to the file % \texttt{mydljs.djs}, as above. It is input back into the document where macros are allowed % to expand, then written back out to another file. The name of this new file is \texttt{mydljs.fdf}. % The file basename comes from the first required parameter of the \texttt{insDLJS} environment. % The file extension \texttt{.fdf} stands for ``forms data format''. This is an extension defined % and recognized by the Acrobat line of products. % % The file \texttt{mydljs.fdf} contains the document level JavaScript in a form that % the Acrobat application (version~5.0 or later) can import. Part of the work of the package % is to define an open page action. When the PDF document is opened for the first time in % Acrobat, the JavaScript is imported. Usually, you open the document following distillation. % After the \texttt{.fdf} file(s) have been imported, you need to save the document, usually using % the ``SaveAs'' file option, this saves the JavaScript code with the file. (There is no need for the % \texttt{.fdf} file(s) at this point). % % \section{Comments on JavaScript} % \subsection{What is Document Level JavaScript?} % The Document level is a location in the PDF document where script can be stored. % When the PDF document is opened, the document level functions are scanned, and any % ``exposed script'' is executed. % % Normally, the type of scripts you would place at the document level are % general purpose JavaScript functions, functions that are called repeatedly or large special % purpose functions. Functions at the document level % are known throughout the document, so they can be called by links, form buttons, page open % actions, etc. % % Variables declared within a JavaScript function have local scope, they are not known outside % that function. However, if you can declare variables and initialize them at the document level outside % of a function, these variables will have document wide scope. Throughout the document, the values of these % global variables are known. For example %\begin{verbatim} %\begin{insDLJS}[HelloWorld]{mydljs}{My Private DLJS} %var myVar = 17; // defined outside a function, global scope %function HelloWorld() %{ % var x = 3; // defined inside a function, local scope % app.alert("\tugHello", 3); %} % \end{insDLJS} %\end{verbatim} % Both the function \texttt{HelloWorld()} and the variable \texttt{myVar} are known throughout % the document. The function \texttt{HelloWorld()} can be called by a mouse up button action; % some form field, executing some JavaScript, may access the value of \texttt{myVar} and/or % change its value. The variable \texttt{x} is not known outside of the \texttt{HelloWorld()} function. % % \subsection{Access and Debugging} % For those who do not have \textsf{Acrobat}, the application, % unless you are writing very simple code, writing and debugging % JavaScript will be very difficult. From the Acrobat Reader, % there is not access to the document level JavaScript. You will be % pretty much writing blind. You can use the debug feature of % \textsf{insdjs} and insert some debugging code to try to give you % some insight into what is going wrong. Even so, debugging will be a problem. % % Normally, I develop the JavaScript from within Acrobat. The GUI editor does check for % syntax errors, giving you a chance to correct some simple errors as you go. After I am satisfied % with my code, I copy it from the editor and paste it into a \texttt{insDLJS} environemnt. This is % how the JavaScript code of \textsf{exerquiz} was developed. % % In my opinion, if you want to develop rather complicated code, having the full Acrobat product % is a must. (This implies the Windows or Mac plateform is needed!) % % \subsection{JavaScript References} % The JavaScript used by Acrobat consists of the core JavaScript plus Acrobat's JavaScript extensions. % Acrobat~5.0 uses core JavaScript~1.5, see\newline % \strut{\small\url{http://developer.netscape.com/docs/manuals/index.html?content=javascript.html}}\newline\noindent % and documentation of the Acrobat extensions can be found in the ``Acrobat JavaScript Object Specification'' % by Carl Orthlieb and D. P. Story. see\newline % \strut{\small\url{http://partners.adobe.com/asn/developer/technotes/acrobatpdf.html}} % \section{Package Options and Requirements} % % \subsection{Package Options} % The options are \texttt{dvipsone}, \texttt{dvips}, \texttt{pdftex} and % \texttt{dvipdfm}. The default is \texttt{dvipsone}/\texttt{dvips}. % \begin{macrocode} %<*package> % \end{macrocode} % \begin{macro}{dvipsone} % \begin{macro}{dvips} % \begin{macro}{pdftex} % \begin{macro}{dvipdfm} % Standard driver options.\par\medskip\noindent % \textbf{Those using Distiller 5.0} % \begin{macrocode} \DeclareOption{dvipsone}{\def\dljs@drivernum{0}\let\isOpenAction=y} \DeclareOption{dvips}{\def\dljs@drivernum{0}\let\isOpenAction=y} % \end{macrocode} %\textbf{Those not using Distiller} % \begin{macrocode} \DeclareOption{pdftex}{\def\dljs@drivernum{1}\let\isOpenAction=n} \DeclareOption{dvipdfm}{\def\dljs@drivernum{2}\let\isOpenAction=n} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % Set the default value of the driver: assume the distiller is used. % \begin{macrocode} \def\dljs@drivernum{0} % \end{macrocode} % \begin{macro}{nodljs} % Option to cancel the insertion of DLJS, useful for a document meant to be % printed only, or one that does not use the \texttt{shortquiz} or % \texttt{quiz} environments, for example. % \begin{macrocode} \DeclareOption{nodljs}{\let\importdljs=n} \let\importdljs=y % \end{macrocode} % \end{macro} % Need to place certain code only once. This switch will make sure of that. % \begin{macrocode} \let\firstdljs=y % \end{macrocode} % \begin{macro}{debug} % Use this option to help debug DLJS. % \begin{macrocode} \DeclareOption{debug}{\let\dljs@debug=y} \let\dljs@debug=n % \end{macrocode} % \end{macro} % \begin{macrocode} \ProcessOptions % \end{macrocode} % \subsection{Required Packages} % We need \texttt{hyperref} to provide some fundamental code for the % various drivers and \texttt{verbatim} to help write verbatim code % to a file. % \begin{macrocode} \RequirePackage{hyperref} \RequirePackage{verbatim} % \end{macrocode} % \section{Main Code} % Some control sequences that are useful for formatting JavaScript. % \begin{macrocode} \def\jsR{\string\r}\def\jsT{\string\t} % \end{macrocode} % Need to write to files. This stream will be used for that purpose. % \begin{macrocode} \newwrite\js@verbatim@out \def\iwvo#1{\immediate\write\js@verbatim@out{#1}} % \end{macrocode} % \subsection{A Macro for Debugging JS} % \begin{macro}{\db...\db} % The \cs{db} macro can be used within the \texttt{insDLJS} to insert % addition JS commads to help debug the code. Usage: %\begin{verbatim} % \db console.println("myVal = " + myVal);\db% %\end{verbatim} % Any material (on one line) that is between the two \verb+\db+ will either be % written to the DLJS (if \cmd{\dljs@debug} expands to \texttt y), or be removed from % the final output (if \cmd{\dljs@debug} does not expand to \texttt y). % % Note that the comment character (|%|) following the terminating \verb+\db+. % This comment keeps a carriage return from being invoked; if \cmd{dljs@debug} is false % then this will not create an empty line in your JavaScript. % \begin{macrocode} \def\js@R{\ifcase\dljs@drivernum^^J\else\jsR\fi} % \end{macrocode} % The three spaces (\cs{space}) is meant to align the debug statement, since |\db| takes % up three spaces. % \begin{macrocode} \def\db#1\db{\ifx\dljs@debug y\space\space\space#1\js@R\fi} % \end{macrocode} % \end{macro} % Acrobat (and Reader) expect the JavaScript code will be listed in the JavaScript % array in sorted form. \texttt{pdftex} and \texttt{dvipdfm} do not sort this array % and it would be difficult for \TeX{} to do the sorting; therefore a workaround. % Each set of DLJS will be numbered in the order in which they are defined. This puts % them naturally in proper sorted order. The following counter, numbers the JS. % \begin{macrocode} \newcounter{dljs@cnt} \newcounter{dljssegs}\setcounter{dljssegs}{2} % \end{macrocode} % \subsection{Some Verbatim Write Environments} % Here is a verbatim write environment, based on an example in the % \texttt{verbatim} package. One modification: The output stream is % not opened by this environment, this must be done prior. This is necessary % to write some other stuff prior to the verbatim write. % % This verbatim is used internally to write the \texttt{.def} files, containing % the JavaScript. % \begin{macrocode} \newenvironment{js@verbatimwrite}% writes to current \js@verbatim@out {% \@bsphack \let\do\@makeother\dospecials\catcode`\^^M\active \def\verbatim@processline{% \immediate\write\js@verbatim@out{\the\verbatim@line}}% \verbatim@start}{\@esphack} % \end{macrocode} % Unlike the example of verbatimwrite in the \texttt{verbatim} package, we do not % automatically close the stream when we finish out \texttt{js@verbatimwrite} environment. % We need to write more to this file, so we have an explicite close. % \begin{macrocode} \def\closejs@verbatim@out{\immediate\closeout\js@verbatim@out} % \end{macrocode} % Same as above, except we expand the line with an \cmd{\edef}. % % For the case of \texttt{dvipsone/dvips}, which use the pdfmark operator, we have % a couple of definitions for escape (esc). It turns out, I find it convenient to have % two versions, a \cs{eqesc}, and a \cs{eqesci}, the latter one is only used once, the the former % one is used numerous times, see the \texttt{\hyperref[dljscc]{dljscc.def}} file. % \begin{macrocode} \begingroup \catcode`\@=0 @catcode`@\=12 @gdef@ccpdfmark{@gdef@eqesc{\}@gdef@eqesci{}} @endgroup % \end{macrocode} % Here's a definition of left and right braces that will be used in writing JavaScript code. % \begin{macrocode} \begingroup \catcode`<=1 \catcode`\>=2 \@makeother\{ \@makeother\} \gdef\definebraces<\gdef\{<\eqesc{> \gdef\}<\eqesc}>> \endgroup % \end{macrocode} % My own special dos and don'ts. Preserve |\| and \texttt{\%} % \begin{macrocode} \def\eqdospecials{\do\ \do\{\do\}\do\$\do\&% \do\#\do\^\do\_\do\~} % \end{macrocode} % The \texttt{jsexpverbatimwrite} environment is used to write a quasi-verbatim % file. We keep original default definitions of |\| and |%| (they are not included in the % \cs{eqdospecials} above). The code for \texttt{jsexpverbatimwrite} is based on that found % in the \texttt{verbatim} package. The trouble is, this package assumes that |\| has been changed % to catcode 12, other. Consequently, I had a devil of a time trying to stop the verbatim write % with |\| as an escape rather than other. I finally decided it was necessary to rewrite some of % the main macros in \texttt{verbatim} so they would properly stop. Below are the modifications % designed to stop when \texttt{*end} encountered rather than \cs{end}. These changes seem to % work o.k. % \begin{macrocode} \begingroup \catcode`\~=\active \lccode`\~=`\^^M \lowercase{\endgroup \def\eqverbatim@#1~{\verbatim@@#1*end\@nil}% \def\eqverbatim@@#1*end{% \verbatim@addtoline{#1}% \futurelet\next\eqverbatim@@@}% \def\eqverbatim@@@#1\@nil{% \ifx\next\@nil \verbatim@processline \verbatim@startline \let\next\eqverbatim@ \else \def\@tempa##1*end\@nil{##1}% \@temptokena{*end}% \def\next{\expandafter\verbatim@test\@tempa#1\@nil~}% \fi \next}% }% \def\jsexpverbatimwrite {% writes to current \js@verbatim@out \@bsphack % \escapechar=-1% \ccpdfmark \input{dljscc.def}% % Attempt to redefine some macros from the the verbatim package \let\verbatim@=\eqverbatim@ \let\verbatim@@=\eqverbatim@@ \let\verbatim@@@=\eqverbatim@@@ % end redefine of verbatim package \let\do\@makeother\eqdospecials% \catcode`\^^M=\active\catcode`\^^I=12% \def\verbatim@processline{% \edef\expVerb{\the\verbatim@line}% \immediate\write\js@verbatim@out{\expVerb}}% \verbatim@start% } \def\endjsexpverbatimwrite{\immediate\closeout\js@verbatim@out\@esphack} % \end{macrocode} % \begin{macro}{\insPath} % Set this macro in the \textbf{preamble} of your document to % direct (almost) all auxiliary files of insDLJS to the specified % path. The macro takes one parameter, a path on your local hard % disk. Usage: %\begin{verbatim} %\insPath{c:/temp/} %\end{verbatim} % Be sure to use only forward slashes, and don't forget to finish % the string with a final forward slash, as illustrated above. % % All \texttt{*.fdf} files are written to this folder. The % \texttt{.def} files of any \texttt{insDLJS} environments created % after the \cmd{\insPath} will also be written to the path. Any % \texttt{.def} created by packages loaded earlier (such as % \textsf{exerquiz}) will be written to the current directory. % % This macro may be useful for users of Distiller~5.0, and is of marginal % value to users of \textsf{pdftex/dvipdfm}. % \begin{macrocode} \let\js@Path=\empty \def\insPath#1{\def\js@Path{#1}} % \end{macrocode} % \end{macro} % % \subsection{Open Page Actions}\label{openaction} % % In order to get automatic insertion of DLJS using Distiller~5.0 or greater, it is necessary % to use a ``Page Open Action'' for page 1 of the document. This section contains some commands % for defining an open page action. Originally, these macros were defined only for Distiller % users (\textsf{dvips} and \textsf{dvipsone} users), later, I extended their use to % \textsf{pdftex} and \textsf{dvipdfm}. % % Here are the macros that actually place the open page action into the PDF document. One for % the \textsf{Distiller}, one for \textsf{pdftex}, and one for \textsf{dvipdfm}. % \begin{macrocode} \def\@OAction@pdfmark{\literalps@out{% [ {ThisPage} << /AA << /O << \theFirstAction\space \the\opentoks\@rightDelimiters >> >> >> /PUT pdfmark}} \def\@OAction@pdftex{\ifx\isOpenAction y% \xdef\pdftexOAction{/AA << /O << \theFirstAction\space \the\opentoks\@rightDelimiters >> >>} \pdfpageattr=\expandafter{\pdftexOAction}\fi} \def\@OAction@dvipdfm{\ifx\isOpenAction y% \@pdfm@mark{put @thispage << /AA << /O << \theFirstAction\space \the\opentoks\@rightDelimiters >> >> >>}\fi} % \end{macrocode} % Now we choose the one approprate to the user's driver option. % \begin{macrocode} \ifcase\dljs@drivernum \let\@OAction=\@OAction@pdfmark \gdef\theFirstAction{/S /JavaScript /JS (\the\importfdftoks)} \or \let\@OAction=\@OAction@pdftex \AtBeginDocument{\@OAction@pdftex} \or \let\@OAction=\@OAction@dvipdfm \AtBeginDocument{\@OAction@dvipdfm} \fi % \end{macrocode} % \begin{macro}{\OpenAction} % In order for the DLJS to be inserted, \texttt{insdljs} places an open page action % on the first page. If the document author wants his/her own open page action, inserting % it with the pdfmark operator may lead to unpredictable results. For the uses of the % Distiller (dvipsone and dvips users of the distiller), if additional open page action % is needed on the first page, you can insert this action using the \cmd{\nextOAction} command. % %\medskip\noindent Usage %\begin{verbatim} %\OpenAction{/S /JavaScript /JS (app.beep(-1); app.alert("Welcome to my Page!",3);)} %\end{verbatim} % The macro takes to parameters, the \cmd{\Next} followed by the desired action, in this % case it is a JavaScript action. % % From the code below, you can see that \cmd{\nextOAction} ends calling itself. If the next token % is a \cmd{\Next}, additional code is entered into the open page action. Thus, for example, the % following code is effectively the same as the above example, but the individual lines are % listed separately in the GUI action dialog of Acrobat. %\begin{verbatim} %\OpenAction %{/S /JavaScript /JS (app.beep(-1);)} %\Next{/S /JavaScript /JS (app.alert("Welcome to my Page!",3);)} %\end{verbatim} % In this was, you can ``chain action'' together'' several open page actions. % % You are not restricted to JavaScript actions, for example, you can perform a \texttt{Named} % action: %\begin{verbatim} %\OpenAction{/S /Named /N /Open} %\end{verbatim} % %\medskip\noindent \cs{opentoks} accumulates the ``action''. % \begin{macrocode} \newtoks\opentoks \opentoks={} % \end{macrocode} % The open action is really not meant for anything too fancy, such as searching using regular % expressions. Of the special characters, we include only \cs{r} and \cs{t} for formatting % purposes. If you want to use a regular expression in the open page action (not likely), % put it at the document level as a JavaScript function, and call that funtion from the % open page action. % \begin{macrocode} \def\makespecialJS{\let\r=\jsR\let\t=\jsT} \def\@rightDelimiters{} % \end{macrocode} % If the next token is \cs{Next} then we gobble it up, and begin \cs{@OpenAction} % otherwise we begin \cs{@OpenAction}. This allows the ``chaining'' as illustrated above. % \begin{macrocode} \def\OpenAction{\@ifnextchar\Next {\expandafter\@OpenAction\@gobble}{\@OpenAction}} % \end{macrocode} % \cs{@OpenAction}: This is the macro that actually does the work. We differentiate between whether the % current argument \texttt{\#1} is the first of all open actions, or not. If the former, % we define it as \cs{theFirstAction}, and reset \cs{isOpenAction}, which keeps track of % whether there has been a \textit{prior} open action defined. If the latter, we place it in % the \cs{opentoks} token register. % \begin{macrocode} \def\@OpenAction#1{% \ifx\isOpenAction n% {\makespecialJS\xdef\theFirstAction{#1}} \global\let\isOpenAction y% \else \edef\dljstmp{\@rightDelimiters}% \edef\@rightDelimiters{\dljstmp >> }% {\makespecialJS\xdef\dljstmp{\the\opentoks /Next << #1 }}% \opentoks=\expandafter{\dljstmp}% \fi \@nextOpenAction } % \end{macrocode} % As its last act, \cs{@OpenAction} calls \cs{@nextOpenAction}, which is nearly identical to % \cs{OpenAction}, except if there is no \cs{Next} token, the macro terminates. % \begin{macrocode} \def\@nextOpenAction{\@ifnextchar\Next{\expandafter\@OpenAction\@gobble}{}} % \end{macrocode} % \end{macro} % Here is a last example that uses the \texttt{insDLJS} environment and the \cs{OpenAction} command. This code % will cause the following action: Ten seconds after the document is opened, an annoying % message is placed on the screen. The annoying message appears only \texttt{once}, otherwise, % it would really be annoying. Reader (Acrobat)~5.0 is required for this code. %\begin{verbatim} %\begin{insDLJS}[DoIt]{doit}{DoIt} %var timeout; %var didIt = false; %var myWelcome = "Welcome to your PDF Page!\r\r You can remove this annoying" % +" message by sending \u00A3100 to my Swiss bank account!" %function startToDoIt() %{ % if(!didIt) timeout = app.setInterval("DoIt();", 10000); %} %function DoIt() %{ % app.beep(-1); % app.alert(myWelcome,1); % app.clearInterval(timeout); % didIt = true; %} %\end{insDLJS} %\OpenAction{/S /JavaScript /JS(startToDoIt();)} %\end{verbatim} % See the ``Acrobat JavaScript Object Specification'' for the definitions of some % of these JavaScript methods. % % \subsection{The \texttt{insDLJS} Environments} % % \begin{macro}{insDLJS}\hypertarget{insDLJS}{} % \begin{macro}{insDLJS*} % This is the main environments defined by this package. These environments % first set some global variables, then set the program flow to driver-dependent % environments. There are two forms of this environment, the \texttt{insDLJS} and the % \texttt{insDLJS*}. % % The \texttt{insDLJS} is the simplest of the two environments. Any material % within the environment, eventually ends up in the DLJS section of the % PDF document % % The environment takes the \texttt{} and writes the % file \texttt{.def}. This file contains a verbatim % listing of the JS within the environment, plus some changing of % catcodes. This file is then input back into the document at % \cmd{\AtBeginDocument} with the necessary code for % \textsf{pdftex} and \textsf{dvipdfm} properly place the JS. % % The case of \textsf{dvipsone} and \textsf{dvips} is a little different. A % \texttt{.def} is written and input back, and a second file % \texttt{.fdf} is written. This second file is later input % into the PDF document after distillation. % % The syntax of usage for this environment, which takes three % arguments, is given next. % \begin{verbatim} % \begin{insDLJS}[]{}{} % % ... % ... % \end{insDLJS} % \end{verbatim} % where, % \begin{description} % \item[\texttt{\#1:}] This optional parameter, \texttt{}, % is \emph{required} for the \texttt{dvipsone} and \texttt{dvips} % options; otherwise it is ignored. It's value must be the name of % one of the functions defined in the environment. This is used to % detect whether the DLJS has already be loaded by Acrobat. % \item[\texttt{\#2}:] This parameter, \texttt{}, is an % alphabetic word with no spaces and limited to eight characters. It % is used to build the names of auxiliary files and to build the % names of macros used by the environment. % \item[\texttt{\#3}:] The \texttt{} of your JavaScript. % This title will appear in the Document-level JavaScript dialog of % Acrobat. % \end{description} % Within the insDLJS environment, there are two types of comment characters: % (1) a \TeX{} comment (|%|) and (2) a JavaScript comment. The JavaScript % comments are `\texttt{//}', a line comment, and `\texttt{/*...*/}' for more % extensive commenting. These comments will survive and be placed into the % PDF file. In JavaScript the `|%|' is used as well, use |\%| when you want to use % the percent character in a JavaScript statement, for example % |app.alert("\%.2f", 3.14159);|, this statement will appear within your JavaScript % code as |app.alert("%.2f", 3.14159);|. % % \begin{macrocode} \newenvironment{insDLJS}[3][] {% \gdef\detectdljs{#1}\gdef\dljsBase{#2}\gdef\dljsName{#3}% \global\let\multisegments=n\setcounter{dljssegs}{2}\global\dljsobjtoks={}% \expandafter\ifx\csname dljs\dljsBase\endcsname\relax \else\@insjserrDuplicate\fi \ifcase\dljs@drivernum \let\insert@DLJS=\insert@DLJS@pdfmark \let\endinsDLJS=\endinsert@DLJS@pdfmark \let\newsegment=\newsegment@pdfmark \let\endnewsegment=\endnewsegment@pdfmark \or \let\insert@DLJS=\insert@DLJS@pdftex \let\endinsDLJS=\endinsert@DLJS@pdftex \let\newsegment=\newsegment@pdftex \let\endnewsegment=\endnewsegment@pdftex \or \let\insert@DLJS=\insert@DLJS@dvipdfm \let\endinsDLJS=\endinsert@DLJS@dvipdfm \let\newsegment=\newsegment@dvipdfm \let\endnewsegment=\endnewsegment@dvipdfm \fi \insert@DLJS }{} % \end{macrocode} % % The \texttt{insDLJS*} environment can be used to better organize, % edit and debug your JavaScript. If you have the full Acrobat % product, you can open the DLJS edit dialog. There you will see a % listing of all DLJS contained in the document. When you double % click on one of the \textsl{script names}, you enter the edit % window, where you can edit all JavaScript contained under that % name. Each \texttt{insDLJS} environment creates a new listinging % within this DLJS dialog; and, each environment creates a % `\texttt{.def}' file and possibly a \texttt{.fdf}' file. Each % \texttt{insDLJS*} environment also creates a `\texttt{.def}' file % and possibly a `\texttt{.fdf}' file too, but withing the % \texttt{insDLJS*} environment you can create JavaScript under % different \textsl{script names}. % % The syntax is % \begin{verbatim} % \begin{insDLJS*}[]{} % \begin{newsegment}{} % % \end{newsegment} % \begin{newsegment}{} % % \end{newsegment} % ... % ... % % \end{newsegment} % \begin{newsegment}{} % % \end{newsegment} % \end{insDLJS*} % \end{verbatim} % where, % \begin{description} % \item[\texttt{\#1:}] This optional parameter, \texttt{}, % is \emph{required} for the \texttt{dvipsone} and \texttt{dvips} % options; otherwise it is ignored. It's value must be the name of % one of the functions defined in the environment. This is used to % detect whether the DLJS has already be loaded by Acrobat. % \item[\texttt{\#2}:] This parameter, \texttt{}, is an % alphabetic word with no spaces and limited to eight characters. It % is used to build the names of auxiliary files and to build the % names of macros used by the environment. % \item[\texttt{\#3}:] The \texttt{} of your JavaScript. % This title will appear in the Document-level JavaScript dialog of % Acrobat. % \end{description} % % \begin{macrocode} \newenvironment{insDLJS*}[2][] {% \gdef\detectdljs{#1}\gdef\dljsBase{#2}% \global\let\multisegments=y\setcounter{dljssegs}{2}\global\dljsobjtoks={}% \expandafter\ifx\csname dljs\dljsBase\endcsname\relax \else\@insjserrDuplicate\fi \ifcase\dljs@drivernum \let\insert@DLJS=\insert@DLJS@pdfmark \expandafter\let\csname endinsDLJS*\endcsname=\endinsert@DLJS@pdfmark \let\newsegment=\newsegment@pdfmark \let\endnewsegment=\endnewsegment@pdfmark \or \let\insert@DLJS=\insert@DLJS@pdftex \expandafter\let\csname endinsDLJS*\endcsname=\endinsert@DLJS@pdftex \let\newsegment=\newsegment@pdftex \let\endnewsegment=\endnewsegment@pdftex \or \let\insert@DLJS=\insert@DLJS@dvipdfm \expandafter\let\csname endinsDLJS*\endcsname=\endinsert@DLJS@dvipdfm \let\newsegment=\newsegment@dvipdfm \let\endnewsegment=\endnewsegment@dvipdfm \fi \insert@DLJS }{} \def\@insjserrDuplicate{% \typeout{^^J! insdljs Package error.} \typeout{! insDLJS environment: On line number \the\inputlineno,} \typeout{! the base name `\dljsBase' has already been chosen.} \typeout{! A DLJS earlier defined has been overwritten!} \typeout{! Choose another name for the first required argument} \typeout{! of the insDLJS environment.^^J} } % \end{macrocode} % \end{macro} % \end{macro} % \subsection{For \texttt{dvipsone}/\texttt{dvips}} % The method of automatic insertion of document-level JavaScript is to % write an FDF file (Forms Data Format), then import this FDF into the % document using the JavaScript method \texttt{Doc.importAnFDF()}. % % We break the FDF file into three parts: the \cmd{\fdfheader} (the stuff prior % to the JavaScript code); the JavaScript code itself; and the % \cmd{\fdftrailer}, the stuff that follows the code. % \begin{macrocode} \begingroup \catcode`\%=12 \gdef\firstFDFline{%FDF-1.2} \gdef\lastFDFline{%%EOF} \endgroup \def\fdfheader {% \iwvo{\string\begingroup} \iwvo{\string\makeatletter} \iwvo{\string\immediate\string\openout\string\js@verbatim@out=\string\js@Path\space\dljsBase.fdf}% \iwvo{\string\begin{jsexpverbatimwrite}} \iwvo{\string\firstFDFline} \iwvo{1 0 obj} \iwvo{<< /FDF << /JavaScript << /Doc 2 0 R >> >> >>} \iwvo{endobj} \iwvo{2 0 obj} \iwvo{[ \csname \dljsBase OBJ\endcsname]} \iwvo{endobj} } \def\fdfbeginstreamobj {% \iwvo{\thedljssegs\space 0 obj} \iwvo{<<>>} \iwvo{stream} } \def\fdfendstreamobj{% \iwvo{endstream} \iwvo{endobj}} \def\fdftrailer{% \iwvo{trailer} \iwvo{<< /Root 1 0 R >>} \iwvo{\string\lastFDFline} % \end{macrocode} % Here we write \texttt{*end{jsexpverbatimwrite}} as a signal for our modified verbatim write % code to stop. % \begin{macrocode} \iwvo{*end{jsexpverbatimwrite}} \iwvo{\string\endgroup} } % \end{macrocode} % There may be more than one use of the \texttt{insDLJS} % environment and we need to be able to import each of the resultant % FDF files. The \cmd{\importfdftoks} accumulates material to be % used after all chance for the user to insert JS code has been % exhausted. % \begin{macrocode} \newtoks\importfdftoks \importfdftoks={} \newtoks\dljsobjtoks \dljsobjtoks={} % \end{macrocode} % This is a template for detecting whether the DLJS has been imported into % the document. % \begin{macrocode} \def\importAnFDFTemplate{% if (typeof \detectdljs\space == "undefined")\jsR\jsT this.importAnFDF("\noexpand\js@Path\dljsBase.fdf");\jsR } % \end{macrocode} % Add in another template into \cmd{\importfdftoks}. % \begin{macrocode} \def\addImportAnFDF{% \ifx\importdljs y% \edef\importAnFDFtmp{\the\importfdftoks\importAnFDFTemplate}% \global\importfdftoks=\expandafter{\importAnFDFtmp}% \fi } % \end{macrocode} % This is used by \texttt{insert@DLJS@pdfmark} and is placed in the code using % \cmd{\AtBeginDocument}. % \begin{macrocode} \def\importAnFDF{\ifx\importdljs y\@OAction\fi} % \end{macrocode} % The \texttt{insert@DLJS@pdfmark} environment write the \cmd{\dljsBase.def} file % which is in turn input back in, and rewritten as \cmd{\dljsBase.fdf}. This is % necessary to give the user a chance to modify the JavaScript code in an % authorized way. % \begin{macrocode} \newenvironment{newsegment@pdfmark}[1]{% \addtocounter{dljssegs}{1}% \addtocounter{dljs@cnt}{1}% \edef\@dljstmp{\the\dljsobjtoks(#1) \thedljssegs\space 0 R\space} \global\dljsobjtoks=\expandafter{\@dljstmp} \fdfbeginstreamobj \js@verbatimwrite }{% \fdfendstreamobj \endjs@verbatimwrite } \def\insert@DLJS@pdfmark{% \expandafter\gdef\csname dljs\dljsBase\endcsname{}% \ifx\importdljs y% \addImportAnFDF \fi \immediate\openout \js@verbatim@out \js@Path\dljsBase.djs % \immediate\openout \js@verbatim@out \js@Path\dljsBase.def \fdfheader \ifx\multisegments n\expandafter\newsegment\expandafter{\expandafter\dljsName\expandafter}\fi } \def\endinsert@DLJS@pdfmark{% \ifx\importdljs y% \ifx\multisegments n\expandafter\endnewsegment\fi \fdftrailer \closejs@verbatim@out \expandafter\xdef\csname\dljsBase OBJ\endcsname{\the\dljsobjtoks} \edef\@dljstmp{\noexpand\AtBeginDocument{\noexpand\input{\js@Path\dljsBase.djs}}}% % \edef\@dljstmp{\noexpand\AtBeginDocument{\noexpand\input{\js@Path\dljsBase.def}}}% \@dljstmp \ifx\firstdljs y% \AfterBeginDocument{\edef\@dljstmp{\importAnFDF}\@dljstmp}\global\let\firstdljs=n% % \AtEndDocument{\edef\@dljstmp{\importAnFDF}\@dljstmp}\global\firstdljsfalse \fi \fi } % \end{macrocode} % \subsection{For \texttt{pdftex}/\texttt{dvipdfm}} % Again, we break the problem of creating DLJS into four parts: \cmd{\begindljs}, % \cmd{\enddljs}, the code itself, driver dependent material, \cmd{\write@pdftex@obj} % and \cmd{\write@dvipdfm@obj}. % % The following is used by both \texttt{pdftex} and \texttt{dvipdfm}. % \begin{macrocode} \begingroup \catcode`\@=0 @catcode`@\=12 @gdef@ccpdftex{@gdef@eqesc{\\}@gdef@eqesci{\}} @endgroup \def\begindljs {% \iwvo{\string\begingroup} {\uccode`c=`\%\uppercase{\iwvo{\string\obeyspaces\string\obeylines\string\global\string\let\string^\string^M=\string\jsR c}}} } \def\beginseg {% {\lccode`P=`\{\lccode`C=`\%\lowercase{\iwvo{\string\gdef\string\dljs\dljsBase\roman{dljssegs}PC}}}% } % \end{macrocode} % With \cs{enddsljs}, we now finish the macro definition with a closing right brace, followed by a % comment, `\texttt\%, and an end of group. % \begin{macrocode} \def\endseg {% {\uccode`c=`\%\uccode`p=`\}\uppercase{\iwvo{pc}}}% } \def\enddljs {% \iwvo{\string\endgroup}% } % \end{macrocode} % \begin{macrocode} \def\write@objs {% \iwvo{\begingroup} {\lccode`C=`\%\lowercase{\iwvo{\string\ccpdftex C}}} {\lccode`C=`\%\lowercase{\iwvo{\string\input{dljscc.def}C\the\dljsobjtoks}}} \iwvo{\endgroup} \iwvo{\string\endinput}% } % \end{macrocode} % \subsubsection{\texttt{pdftex} Specific Code} % \begin{macrocode} \newenvironment{newsegment@pdftex}[1]{% \addtocounter{dljssegs}{1}% \addtocounter{dljs@cnt}{1}% \edef\tmp{^^J\string\immediate\string\pdfobj{ << /S /JavaScript /JS (\string\dljs\dljsBase\roman{dljssegs}) >> }} \edef\@dljstmp{\the\dljsobjtoks\tmp} \global\dljsobjtoks=\expandafter{\@dljstmp} \edef\tmp{^^J\string\xdef\string\obj\dljsBase\roman{dljssegs}{\string\the\string\pdflastobj\string\space 0 R}} \edef\@dljstmp{\the\dljsobjtoks\tmp} \global\dljsobjtoks=\expandafter{\@dljstmp} \edef\dljspdftextmp {\the\importfdftoks (\arabic{dljs@cnt} #1) \noexpand\csname obj\dljsBase\roman{dljssegs}\noexpand\endcsname\space}% \global\importfdftoks=\expandafter{\dljspdftextmp}% \beginseg \js@verbatimwrite }{% \endjs@verbatimwrite \endseg } % \end{macrocode} % The main branch of the \texttt{insDLJS} for \texttt{pdftex}. This % environment writes to the file \cmd{\dljsBase.def} all the necessary code, then % is input back into the file using \cmd{\AtBeginDocument}. % \begin{macrocode} \newenvironment{insert@DLJS@pdftex}{% \expandafter\gdef\csname dljs\dljsBase\endcsname{}% \immediate\openout \js@verbatim@out \js@Path\dljsBase.djs % \immediate\openout \js@verbatim@out \js@Path\dljsBase.def \begindljs \ifx\multisegments n\expandafter\newsegment\expandafter{\expandafter\dljsName\expandafter}\fi }{% \ifx\multisegments n\expandafter\endnewsegment\fi \enddljs \write@objs \endjs@verbatimwrite \closejs@verbatim@out \edef\@dljstmp{\noexpand\AtBeginDocument{\noexpand\input{\js@Path\dljsBase.djs}}}% % \edef\@dljstmp{\noexpand\AtBeginDocument{\noexpand\input{\js@Path\dljsBase.def}}}% \@dljstmp \ifx\importdljs y% \ifx\firstdljs y% \AtEndDocument{\edef\@dljstmp{\setDLJSRef@pdftex}\@dljstmp} \global\let\firstdljs=n% \fi \fi } % \end{macrocode} % This code places the \texttt{/JavaScript} key-value in the \texttt{/Names} dictionary % of the PDF document. This code is inserted into the document in \texttt{insert@DLJS@pdftex} % using \cmd{\AtEndDocument}. % \begin{macrocode} \def\setDLJSRef@pdftex {% \noexpand\immediate\noexpand\pdfobj {% << /Names [\the\importfdftoks] >> }% \edef\noexpand\objNames{\noexpand\the\noexpand\pdflastobj\space 0 R}% \pdfnames {/JavaScript \noexpand\objNames}% } % \end{macrocode} % \subsubsection{\texttt{dvipdfm} Specific Code} % Begin by writing driver-specific code to \cmd{\dljsBase.def}. % \begin{macrocode} \newenvironment{newsegment@dvipdfm}[1] {% \addtocounter{dljssegs}{1}% \addtocounter{dljs@cnt}{1}% \edef\tmp{^^J\string\immediate\string\csname\space @pdfm@mark\string\endcsname {obj @obj\dljsBase\roman{dljssegs}\space << /S /JavaScript /JS (\string\dljs\dljsBase\roman{dljssegs}) >> }}% \edef\@dljstmp{\the\dljsobjtoks\space\tmp} \global\dljsobjtoks=\expandafter{\@dljstmp} \edef\dljspdftextmp {\the\importfdftoks (\arabic{dljs@cnt} #1) @obj\dljsBase\roman{dljssegs}\space}% \global\importfdftoks=\expandafter{\dljspdftextmp}% \beginseg \js@verbatimwrite }{% \endjs@verbatimwrite \endseg } % \end{macrocode} % This code places the \texttt{/JavaScript} key-value in the \texttt{/Names} dictionary % of the PDF document. This code is inserted into the document in \texttt{insert@DLJS@dvipdfm} % using \cmd{\AtEndDocument}. % \begin{macrocode} \def\setDLJSRef@dvipdfm {% \immediate\@pdfm@mark{obj @objnames << /Names [\the\importfdftoks] >> }% \@pdfm@mark{put @names << /JavaScript @objnames >> }% } % \end{macrocode} % The main branch of the \texttt{insDLJS} for \texttt{dvipdfm}. This % environment writes to the file \cmd{dljsBase.def} all the necessary code, then % is input back into the file using \cmd{\AtBeginDocument}. % \begin{macrocode} \newenvironment{insert@DLJS@dvipdfm} {% \expandafter\gdef\csname dljs\dljsBase\endcsname{}% \immediate\openout \js@verbatim@out \js@Path\dljsBase.djs % \immediate\openout \js@verbatim@out \js@Path\dljsBase.def \begindljs \ifx\multisegments n\expandafter\newsegment\expandafter{\expandafter\dljsName\expandafter}\fi }{% \ifx\multisegments n\expandafter\endnewsegment\fi \enddljs \write@objs \endjs@verbatimwrite \closejs@verbatim@out \edef\@dljstmp{\noexpand\AtBeginDocument{\noexpand\input{\js@Path\dljsBase.djs}}}% % \edef\@dljstmp{\noexpand\AtBeginDocument{\noexpand\input{\js@Path\dljsBase.def}}}% \@dljstmp \ifx\importdljs y% \ifx\firstdljs y% \AtEndDocument{\setDLJSRef@dvipdfm} \global\let\firstdljs=n% \fi \fi } % % \end{macrocode} % \begin{macrocode} %<*cc4js> % \end{macrocode} %\section{Command Changes for JavaScript}\label{dljscc} % Regular expressions are a very important part of JavaScript, but they do present % some problems for \LaTeX. Ideally, we would like to type JavaScript code into the % \texttt{insDLJS} environment using standard JavaScript syntax. % (Whether I am successful remains to be seen.) As a result, some new definitions % and changes in old definitions are necessary. All definitions take place within a % group, so they are unknown outside the \texttt{insDLJS} environment. % %\subsection{Regular Expressions} % Regular expressions can be constructed in two ways, by using (1) a literal text format; or (2) % using the \texttt{RegExp} constructor function. The literal text format: %\begin{flushleft} %\texttt/\textsl{pattern}\texttt/\textsl{flags} %\end{flushleft} % The \texttt{RegExp} constructor method: %\begin{flushleft}\ttfamily %new RegExp("\textsl{pattern}" [, "\textsl{flags}"]) %\end{flushleft} % For additional details on regular expressions, see %\begin{flushleft}\small %\url{http://developer.netscape.com/docs/manuals/js/core/jsref15/regexp.html} %\end{flushleft} % There is a further complication when dealing with regular expressions. To quote from the above % document:\par\medskip\noindent % \textbf{Description } % When using the constructor function, the normal string escape rules (preceding special characters with `|\|' when included in a string) are necessary. % For example, the following are equivalent: % \begin{flushleft} % \ttfamily\obeylines % re = new RegExp("\string\\w+") % re = /\string\w+/ %\end{flushleft} %\subsection{Begin Definitions} % \subsubsection{Handling of Formatting Sequences} % The macro \cmd{\eqesc} expands to `|\|' in the case of the distiller and to `|\\|' in the % case of \textsf{pdftex} or \textsf{dvipdfm}. This group of special characters formats the % output and they require a different definition than most of the others. % % The \cs{ckivspace} (``check for space'') macro sees whether the next token is a space, % if yes, it absorbs is, if not, it replaces it. I implemented this in order to get % final output identical to the JavaScript. For example, the following is legal JavaScript %\begin{verbatim} % var str = "First line.\r\rSkip a line. // (1) %\end{verbatim} % This is a problem for \TeX. In order to delimit the macro, \TeX{} users need to write the % above line as %\begin{verbatim} % var str = "First line.\r\r Skip a line. // (2) %\end{verbatim} % which then introduces a spurious space into the JavaScript code. The \cs{ckivspace} solves this % problem, I hope. With the definition of \cs{r} given below, after expansion of the line (2) % occurs, we have line (1), the space following the second \cs{r} gets absorbed. % \begin{macrocode} \def\ckivspace#1{\if\noexpand#1\space\else\expandafter#1\fi} % \end{macrocode} % \begin{macro}{\r} % Matches a carriage return. % \begin{macrocode} \def\r{\eqesc r\ckivspace} % \end{macrocode} % \end{macro} % \begin{macro}{\t} % Matches a tab. % \begin{macrocode} \def\t{\eqesc t\ckivspace} % \end{macrocode} % \end{macro} % \begin{macro}{\n} % Matches a linefeed. % \begin{macrocode} \def\n{\eqesc n\ckivspace} % \end{macrocode} % \end{macro} % \begin{macro}{\f} % Matches a form-feed. % \begin{macrocode} \def\f{\eqesc f\ckivspace} % \end{macrocode} % \end{macro} % \begin{macro}{\v} % Matches a form-feed. % \begin{macrocode} \def\v{\eqesc v\ckivspace} % \end{macrocode} % \end{macro} % \subsubsection{Matching a Word Boundary or Not} % \begin{macro}{\b} % Matches a word boundary, such as a space. (Not to be confused with |[\b]|, which % matches a backspace.) % \begin{macrocode} \def\b{\eqesc b\ckivspace} % \end{macrocode} % \end{macro} % The next group are all defined in the same way, pretty much. The macro \cmd{\eqesc} expands to `|\|' % in the case of the distiller options, and to `|\\\|' otherwise. % \begin{macro}{\B} % Matches a non-word boundary. % \begin{macrocode} \def\B{\eqesc B\ckivspace} % \end{macrocode} % \end{macro} % \begin{macro}{\cX} % Where X is a letter from A - Z. Matches a control character in a string. Doesn't seem to have % much use in Acrobat JavaScript, will comment this one out. Usage: \cs{cM} % \begin{macrocode} % \def\doAlpha{\do A\do B\do C\do D\do E\do F% % \do G\do H\do I\do J\do K\do K\do M\do N% % \do O\do P\do Q\do R\do S\do T\do U\do V\do W\do X\do Y\do Z} % \def\mkDefns#1{\expandafter\def\csname c#1\endcsname{\eqesc c#1}} % \let\do=\mkDefns\doAlpha % \end{macrocode} % \end{macro} % \subsubsection{Matching Digits or Not} % \begin{macro}{\d} % Matches a digit character. Equivalent to \texttt{[0-9]}. % \begin{macrocode} \def\d{\eqesc d\ckivspace} % \end{macrocode} % \end{macro} % \begin{macro}{\D} % Matches any non-digit character. Equivalent to |[^0-9]|. % \begin{macrocode} \def\D{\eqesc D\ckivspace} % \end{macrocode} % \end{macro} %\subsubsection{Matching Whitespaces or Not} % \begin{macro}{\s} % Matches a single white space character, including space, tab, form feed, line feed. % Equivalent to |[\f\n\r\t\u00A0\u2028\u2029]|. % \begin{macrocode} \def\s{\eqesc s\ckivspace} % \end{macrocode} % \end{macro} % \begin{macro}{\S} % Matches a single character other than white space.\newline % Equivalent to |[^ \f\n\r\t\u00A0\u2028\u2029]|. % \begin{macrocode} \def\S{\eqesc S\ckivspace} % \end{macrocode} % \end{macro} %\subsubsection{Matching Alphanumeric Characters or Not} % \begin{macro}{\w} % Matches any alphanumeric character including the underscore. Equivalent to |[A-Za-z0-9\_]|. % \begin{macrocode} \def\w{\eqesc w\ckivspace} % \end{macrocode} % \end{macro} % \begin{macro}{\W} % Matches any non-word character. Equivalent to |[^A-Za-z0-9_]|. % \begin{macrocode} \def\W{\eqesc W\ckivspace} % \end{macrocode} % \end{macro} % \subsubsection{Handling of Character Codes} % \begin{macro}{\xXX} % Matches the character with the code \texttt{XX} (two hexadecimal digits). % The character with the Latin-1 encoding specified by the two hexadecimal digits \texttt{XX} % between 00 and FF. For example, \cs{xA9} is the hexadecimal sequence for the copyright % symbol. %\begin{flushleft} %\textbf{Usage} %\begin{verbatim} %\x9A %\end{verbatim} %if the most significant digit is a number \texttt{[0-9]}, %\begin{verbatim} %\x A9 %\end{verbatim} %if the most significant digit is a letter \texttt{[a-fA-F]} %\end{flushleft} % \begin{macrocode} \def\x{\eqesc x\ckivspace} % \end{macrocode} % \end{macro} % \begin{macro}{\uXXXX} % In a regular expression search, \cs{uXXXX} matches the character % with unicode character code \texttt{XXXX} (four hexadecimal % digits). For example, \cs{u00A9} is the Unicode sequence for the % copyright symbol. See Unicode Escape Sequences. http://www.unicode.org %\begin{flushleft} %\textbf{Usage} %\begin{verbatim} %\u00A9 %\end{verbatim} %if the most significant digit is a number \texttt{[0-9]}, %\begin{verbatim} %\u F0A9 %\end{verbatim} %if the most significant digit is a letter \texttt{[a-fA-F]} %\end{flushleft} % \begin{macrocode} \def\u{\eqesc u\ckivspace} % \end{macrocode} % \end{macro} % \begin{macro}{\XXX} % The character with the Latin-1 encoding specified by up to three octal digits \texttt{XXX} between % 0 and 377. For example, \cs{251} is the octal sequence for the copyright symbol. % % Since this goes only up to octal 377, it suffices to make only the following four definitions. % \begin{macrocode} \def\0{\eqesc0} \def\1{\eqesc1} \def\2{\eqesc2} \def\3{\eqesc3} % \end{macrocode} % \end{macro} %\subsubsection{Other Special Characters} % \begin{macro}{braces} % Braces are a problem when they are unbalanced. In a regular expression, |\{| works properly, but |\\{| works % for the distiller options but not otherwise. For example, if I wanted to replace every instance % of \texttt{\{} with \texttt{(}, we can do this by %\begin{verbatim} % myString = myString.replace( /\{/, "\("); %\end{verbatim} % This works for all options, even though the braces are not balanced. However, when the constructor % function is used, we must double-escape: %\begin{verbatim} % var re = new RegExp("\\{", "g"); % myString = myString.replace( re, "\("); %\end{verbatim} % This works for the distiller options, but not for \texttt{pdftex/dvipdfm}. The reason |\{| works is that % it is a control sequence, defined by the \cmd{\definebraces} command below. Where as |\\{| consists % of the control sequence |\\|, which is defined below, followed by a left brace. % \TeX{} still requires the braces to be balanced. % % If you are searching for balanced braces, there should't be a problem, for example, % the code %\begin{verbatim} % var re = new RegExp("\\{|\\}", "g"); % myString = myString.replace( re, "\("); %\end{verbatim} % works correctly. % % To continue the discussion of the problem with searching for % unbalanced braces, one workaround is to balance out the left % brace with a right brace in the form of a JavaScript comment. % This ``fools'' \TeX! For example, %\begin{verbatim} % var re = new RegExp("\\{", "g"); // } % myString = myString.replace( re, "\("); %\end{verbatim} % Finally, we have\par\medskip % \noindent\textbf{The Recommended Workaround:} Use |\\\{| and |\\\}|, e.g., %\begin{verbatim} % var re = new RegExp("\\\{", "g"); % myString = myString.replace( re, "\("); %\end{verbatim} % This is more verbose than needed, but it works for all options! These comments are only for regular expression % strings within the constructor function. Note the replacement text, |\(|, is only escaped. % % Here we define make the definitions for left and right braces. See the definition of \cs{definebraces} % given earlier. % \begin{macrocode} \definebraces % \end{macrocode} % \end{macro} % \begin{macro}{parentheses} % Just as braces can give us problems with \TeX, so too, parentheses can give us problems with % Acrobat JavaScript interpreter. There seems to be a requirement that parentheses be balanced % unless they are properly escaped. Generally, we have no problems in the case of distiller options, % once again \textsf{pdftex} and \textsf{dvipdfm} are causing (me) problems. % % No problems when the regular expression uses the literal string format %\begin{verbatim} % myString = myString.replace(/\(/g, "\["); %\end{verbatim} % The above code works for all options. However, for the constructor function we have some problems % in non-distiller options. If we type instead %\begin{verbatim} % var re = new RegExp("\\(", "g"); % myString = myString.replace(re, "\["); %\end{verbatim} % The above code works for the distiller folks, but not for the % others. In the case of \textsf{pdftex}, I cannot access the UI to % the Doc-level JavaScripts, and the script is undefined. I suspect % the lack of balanced parentheses is the curprit. For example, % consider the code %\begin{verbatim} % var re = new RegExp("\\(|\\)", "g"); % myString = myString.replace(re, "\["); %\end{verbatim} % works. I can access the UI to the DLJS from Acrobat, and the script is defined. Another % example, we can fool the JavaScript interpreter as we did the \TeX{} compiler: %\begin{verbatim} % var re = new RegExp("\\(", "g"); // ) % myString = myString.replace(re, "\["); %\end{verbatim} % Here I have placed a balancing right parenthesis as a JavaScript comment. Both sets of code % work correctly. %\par\medskip %\noindent\texttt{Recommended Workaround:} As in the case of parentheses, a more verbose version % of the script works of all options. %\begin{verbatim} % var re = new RegExp("\\\(", "g"); % myString = myString.replace(re, "\["); %\end{verbatim} % This is only for the case of the constructor function. % \begin{macrocode} \def\({\eqesc\eqesci(} \def\){\eqesc\eqesci)} % \end{macrocode} % \end{macro} % The rest of these definitions are for characters that have a % special meaning when appear in a regular expression. See %\begin{flushleft}\small %\url{http://developer.netscape.com/docs/manuals/js/core/jsref15/regexp.html} %\end{flushleft} % for a description of the meaning for the special characters given below (and above). % To ``escape'' the special meaning of any character, ``escape'' them. % \begin{macrocode} \def\.{\eqesc.} \def\/{\eqesc/} \def\[{\eqesc[} \def\]{\eqesc]} % \end{macrocode} % \begin{macrocode} \def\|{\eqesc|} \def\+{\eqesc+} \def\*{\eqesc*} \def\?{\eqesc?} \def\${\eqesc$} \def\^{\eqesc^} \def\\{\eqesc\eqesc} % \end{macrocode} % The next group of characters have no special meaning in a regular expression, but are using elsewhere % in JavaScript. These definitions may come in handy. % \begin{macrocode} \def\'{\eqesc'} % \end{macrocode} % The \texttt{german} package makes doublequotes, |"|, active, so within the \texttt{insDLJS} % environment, we change its catcode to 12. % \begin{macrocode} \catcode`\"=12 \def\"{\eqesc"} % \end{macrocode} % Here, we define `\texttt{\%}' differently. The percent has no special meaning in regular expressions, % but is used by the \texttt{util.printf()} method. % \begin{macrocode} \catcode`\%=12 \def\%{%} \catcode`\%=14 % \end{macrocode} % The `and' symbol has not special meaning for regular expressions, but is used as a logical `and'. % probably don't need this escape. % \begin{macrocode} \catcode`\& = 12 \def\&{\eqesc&} % \end{macrocode} % \begin{macrocode} % % \end{macrocode} \endinput dvipsone broke \fdftrailer into \fdfendstreamobj and \fdftrailer added \newsegment changed the definition of js@verbatimwrite, now you must manually close the output file. Could have a \insPath{}{} \XXX The character with the Latin-1 encoding specified by up to three octal digits XXX between 0 and 377. For example, \251 is the octal sequence for the copyright symbol. \xXX The character with the Latin-1 encoding specified by the two hexadecimal digits XX between 00 and FF. For example, \xA9 is the hexadecimal sequence for the copyright symbol. \uXXXX The Unicode character specified by the four hexadecimal digits XXXX. For example, \u00A9 is the Unicode sequence for the copyright symbol. See Unicode Escape Sequences. http://www.unicode.org