Techniques of Introducing Document-Level Javascript Into A File From A L Tex Source
Techniques of Introducing Document-Level Javascript Into A File From A L Tex Source
Techniques of Introducing Document-Level Javascript Into A File From A L Tex Source
LATEX Source
D. P. Story
Department of Mathematics and Computer Science, University of Akron, Akron, OH 44325
[email protected]
http://www.math.uakron.edu/~dpstory/
Abstract
The method of introducing Acrobat document-level JavaScript (DLJS) into a
PDF depends on the application used: pdftex or dvipdfm. Until recently, users
of Acrobat’s distiller did not have the ability to automatically introduce such
JavaScript into the document from a LATEX source. For users of Acrobat 5.0, this
situation is, at last, rectified. The focus of this paper is to enumerate, illustrate
and discuss these various methods.
A new package, insDLJS, is also introduced. This package enables both
package and document authors to insert document-level JavaScript.
TUGboat, Volume 22 (2001), No. 3 — Proceedings of the 2001 Annual Meeting 161
D. P. Story
162 TUGboat, Volume 22 (2001), No. 3 — Proceedings of the 2001 Annual Meeting
Techniques of Introducing Document-level JavaScript into a PDF file from a LATEX Source
>> } \AtBeginDocument{\literalps@out{%
\edef\objNames{\the\pdflastobj\space 0 R} [ {Page1} << /AA << /O << /S /JavaScript /JS
\pdfnames {/JavaScript \objNames} (%
} if(typeof HelloWorld == "undefined")\jsR\jsT
Similarly for dvipdfm. this.importAnFDF("dljs.fdf");
Acrobat expects the script names of the DLJS )
>> >> >>
(these are ‘Doc Level JS’ and ‘More DLJS’, in the
/PUT pdfmark}}
example above) to be sorted ; otherwise, the Acro-
bat application does not give editing access to the This code creates an open page action for page 1
scripts that are ‘out-of-sorts’.1 The scripts would of the PDF. When the document is first opened
be accessible from within Acrobat or Reader, but in the Acrobat application, usually immediately fol-
would not necessarily be available for editing within lowing distillation, if the function HelloWorld is not
Acrobat. already defined, the JavaScript method importAn-
FDF will import the specified FDF into the docu-
Acrobat 5.0 For authors that use Acrobat 5.0 (those ment; otherwise, the open action does nothing. The
that use dvips or dvipsone to produce a PostScript JavaScript function HelloWorld will be placed at
file and then distill) the problem is a little more the document-level because of the structure of the
complicated. Version 5.0 comes with an extended FDF file.
FDF (Forms Data Format) specification. This new
specification allows DLJS to be placed within the A Simple Implementation The FDF can be cre-
FDF file. The FDF file is then imported into the
ated and edited as a separate file; however, our
document and the DLJS is inserted. goal was to have all code contained in the LATEX
source file itself. A simple solution would be to use
The Concepts Take our basic HelloWorld Java- a verbatim write to write the necessary code to a
Script function, and place it into the FDF file, which FDF file.
I’ll call dljs.fdf, as follows: For example, consider the following code. It
%FDF-1.2 is assumed that the verbatim package has been
1 0 obj loaded.
<< \makeatletter
/FDF \newwrite \dljs@FDF
<<
/JavaScript % open a stream
<< \immediate\openout\dljs@FDF=dljs.fdf
/Doc 2 0 R \let\verbatim@out=\dljs@FDF
>>
>> % verbatimwrite Environment: Writes to current
>> %\verbatim@out. Based on examples and macros
endobj % of the verbatim package. Set \verbatim@out
2 0 obj % before calling this macro
[ (Doc Level JS) 3 0 R ] \newenvironment{verbatimwrite}
endobj {\@bsphack
3 0 obj \let\do\@makeother\dospecials
<<>> \catcode‘\^^M\active
stream \def\verbatim@processline{%
function HelloWorld() \immediate\write\verbatim@out
{ {\the\verbatim@line}}%
app.alert("Hello World!",3); \verbatim@start}%
} {\immediate\closeout\verbatim@out\@esphack}
endstream
endobj Now write the FDF file from the LATEX source.
trailer << /Root 1 0 R >> \begin{verbatimwrite}
%%EOF %FDF-1.2
1 0 obj
Once this file has been created, it can be in-
<<
serted into the PDF file by including the following /FDF
code in your LATEX document: <<
1 Neither pdftex or dvipdfm sorts the Names array by script /JavaScript
names. <<
TUGboat, Volume 22 (2001), No. 3 — Proceedings of the 2001 Annual Meeting 163
D. P. Story
Multiple Functions Multiple functions can either This environment writes one file (<base>.def),
be written to the same FDF file, or to separate or possibly two files (<base>.def and <base>.fdf).
FDF files. When you import multiple FDF files into In the case of pdftex or dvipdfm options, the
Acrobat using importAnFDF, their script names are <base>.def, which contains the necessary defini-
automatically sorted, see the footnote at the end of tions and code, as discussed in ‘pdftex’, page 162
‘Multiple Functions’, page 162. and the following section on ‘dvipdfm’, is read back
into the output document to set the DLJS code.
Plain TEX Users The above examples illustrate In the distiller case, <base>.def is read in and
the basics of DLJS inclusion. Plain TEX users can second file, <base>.fdf, is written. It is the file
(easily) adapt these techniques to plain TEX. This <base>.fdf that is imported into Acrobat following
is left as an exercise. distillation, as outlined on page 163.
The DLJS defined within the insDLJS environ-
The insDLJS Package
ment in a package and in a preamble of a document
All the code described earlier works very well, and will be included in the PDF document automatically.
is adequate for someone trying to develop materials It is important to choose a base name, <base>, and
for the WWW or for a CD-ROM using a private a script name, <name>, different from any that has
164 TUGboat, Volume 22 (2001), No. 3 — Proceedings of the 2001 Annual Meeting
Techniques of Introducing Document-level JavaScript into a PDF file from a LATEX Source
TUGboat, Volume 22 (2001), No. 3 — Proceedings of the 2001 Annual Meeting 165
D. P. Story
The Problem. The above script will search the using the pdftex/dvipdfm option, it would expand
parameter string for a left parenthesis, ‘(’. When to var x = "\\\\". Tricky!
dvipsone or dvips is used (i.e., the distiller is used), Here is a final complete example.
the <base>.fdf file is created, imported into the \documentclass{article}
PDF file and the script works correctly. When pdftex
\usepackage[dvipdfm]{hyperref}
or dvipdfm is used this code does not work! When \usepackage[dvipdfm]{insdljs}
the file is opened in Acrobat an exception is thrown,
and an error message appears: \newcommand\tugHello{Welcome to TUG 2001!}
SyntaxError: unterminated parenthetical (
In the case of pdftex and dvipdfm, the JavaScript \begin{insDLJS}{mydljs}{My DLJS}
code is written directly to the PDF file, bypassing function HelloWorld()
distiller. The problem with the above code turns out {
to beunbalanced parentheses. (Acrobat treats ‘\(’ as app.alert("@tugHello", 3);
a left parenthesis, not an escaped special character.) }
All special characters, therefore, need to be escaped; function TestForLParen(string)
we want {
if (/@e\@e(/.test(string))
\begin{insDLJS}[<func>]{<base>}{<name>} app.alert("Found Left Parenthesis!",3);
function TestForLParen(string) }
{ \end{insDLJS}
if (/\\\(/.test(string))
app.alert("Found Left Parenthesis!",3); \begin{document}
} \begin{Form}
\end{insDLJS}
This code now works when the option pdftex or \section{Test of the \texttt{insDLJS} Package}
dvipdfm is used; however, when this code is used
with the distiller (with the dvipsone or dvips op- \begin{itemize}
tion), Acrobat 5.0 crashes! \item \PushButton[name=myButton,
onclick={HelloWorld();}]{Button:}
The Solution. We have two opposing problems, \item \TextField
solving one creates another. The solution is to intro- [name=myText,width=2in,
duce a command, \e. (The ‘e’ is for escape.) The keystroke={if(event.willCommit)
macro has two definitions: for the dvipsone and TestForLParen(event.value);}
dvips options, we define \gdef\e{}; for pdftex and ]{Text Field:}
dvipdfm options, we make the following definitions: \end{itemize}
\catcode‘\@=0 @catcode‘@\=12 @gdef@e{\}
\end{Form}
Note that in all cases, we do change the catcode of \end{document}
‘@’ to \catcode‘\@=0. A button and a text field are created. Click on the
Thus, to get the function TestForLParen to be
button to get an alert dialog. Enter some text in
properly defined for all options, we must type:
the field; when the data is committed, the function
\begin{insDLJS}[<func>]{<base>}{<name>} TestForLParen is called, and the field is scanned for
function TestForLParen(string)
a left parenthesis.
{
if (/@e\@e(/.test(string)) A Note to pdftex and dvipdfm Users If you
app.alert("Found Left Parenthesis!",3); plan to make extensive use of DLJS, and to write
} complex functions, such as the ones that appear
\end{insDLJS}
in the exerquiz package, the purchase of the full
This problem is not limited to regular expres- Acrobat suite is strongly recommended.
sions. Anywhere there is an escape character ‘\’, The only way to debug Acrobat JavaScript is
there is a potential for problems. For example, if you through the JavaScript edit window of the Acrobat
want to assign the variable x a value of ‘\’, you would viewer. If you only use Acrobat Reader, there is
have to say, within some insDLJS environment:
very little feedback as to what goes wrong with
var x = "@e\@e\"; a particular script; development and debugging of
app.alert(x, 3); scripts will be a very long and tedious process.
In systems using the dvipsone/dvips, this would All the JavaScripts in the exerquiz package were
expand to var x = "\\"; in contrast, on systems first written from within the JavaScript editor and
166 TUGboat, Volume 22 (2001), No. 3 — Proceedings of the 2001 Annual Meeting
Techniques of Introducing Document-level JavaScript into a PDF file from a LATEX Source
tested. Once the script was operating correctly, it ented packages. With them, an author can
would be copied, and pasted into the exerquiz source develop a document with page size suitable for
file for automatic inclusion. presentations or on-line viewing. These pack-
ages come with other bells and whistles as well.
Final Comments
3. The exerquiz6 package (D. P. Story) defines
Acrobat Reader provides a forms capability and a several environments for creating exercises and
powerful JavaScript engine that can be exploited to quizzes, both multiple choice and fill-in. This
create dynamic, interactive PDF documents. The package makes extensive use of the form fea-
LATEX system with its flexible “plug-in” capabil- tures and (document-level) JavaScript.
ity (LATEX packages) is a solid authoring tool for 4. The insDLJS package gives the package or doc-
creating high-quality typeset content. The LATEX ument author an easy and convenient method
packages that give access to PDF are of including document-level JavaScripts.
1. The hyperref3 package written by Sebastian There are many other packages (e.g., for graphics
Rathz, Heiko Oberdiek, et al., automatically insertion, color creation) too numerous to mention.
creates bookmarks and cross-reference hyper-
links, allows document information fill-in and As a result of the above mentioned packages,
provides basic form creation code, to mention as well as the various applications for producing
a few. This package is fundamental to any PDF (pdftex, dvipdfm and the distiller), an author
author who wants to create PDF documents for now has a fairly complete set of authoring tools for
distribution over the Web. developing such a colorful, visually attractive and
2. The webeq4 (D. P. Story) and pdfscreen5 highly interactive documents.
(Radhakrishnan CV) packages are screen ori-
3 CTAN:macros/latex/contrib/supported/hyperref
4 6 CTAN:macros/latex/contrib/supported/webeq
CTAN:macros/latex/contrib/supported/webeq
5 CTAN:macros/latex/contrib/supported/pdfscreen
TUGboat, Volume 22 (2001), No. 3 — Proceedings of the 2001 Annual Meeting 167