diff options
author | Norbert Preining <norbert@preining.info> | 2017-07-12 23:20:07 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2017-07-12 23:20:07 +0900 |
commit | 6bab4699285d78934a890262fa2a7a3db32b82bd (patch) | |
tree | 2c6c583ea7499567913aadc356cc0fd52dea726b /texmf-dist/source/latex/acroflex | |
parent | f17a8765c35b4b836995b01a5c88c785796b013f (diff) |
add acroflex
Diffstat (limited to 'texmf-dist/source/latex/acroflex')
-rw-r--r-- | texmf-dist/source/latex/acroflex/acroflex.dtx | 1951 | ||||
-rw-r--r-- | texmf-dist/source/latex/acroflex/acroflex.ins | 60 | ||||
-rw-r--r-- | texmf-dist/source/latex/acroflex/doc/acroflex_man.tex | 1073 | ||||
-rw-r--r-- | texmf-dist/source/latex/acroflex/swf/AcroFleX.swf | bin | 0 -> 267347 bytes |
4 files changed, 3084 insertions, 0 deletions
diff --git a/texmf-dist/source/latex/acroflex/acroflex.dtx b/texmf-dist/source/latex/acroflex/acroflex.dtx new file mode 100644 index 00000000..b2c35005 --- /dev/null +++ b/texmf-dist/source/latex/acroflex/acroflex.dtx @@ -0,0 +1,1951 @@ +%\iffalse +%<*copyright> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Acroflex.sty package, %% +%% Copyright (C) 2008 -- 2016 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 of the %% +%% License, or (at your option) any later version. %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%</copyright> +%<package>\NeedsTeXFormat{LaTeX2e}[1997/12/01] +%<package>\ProvidesPackage{acroflex} +%<package> [2016/08/29 v1.6c AcroFLeX: AcroTeX and Adobe Flex (dps)] +%<*driver> +\documentclass{ltxdoc} +\usepackage[colorlinks,hyperindex]{hyperref} +\begin{document} +\def\AcroFLeX{AcroF\kern-.1667em\lower.5ex\hbox{L}\kern-.3eme\kern-.125emX\@} + \GetFileInfo{acroflex.sty} + \title{% + \texorpdfstring + {\AcroFLeX: Merging {Acro\negthinspace\TeX} and FLEX} + {AcroFLeX: Merging AcroTeX and FLEX}} + \author{D. P. Story\\ + Email: \texttt{dpstory@acrotex.net}} + \date{processed \today} + \maketitle + \tableofcontents + \let\Email\texttt + \DocInput{acroflex.dtx} + \PrintIndex +\end{document} +%</driver> +% \fi +% \MakeShortVerb{|} +% \StopEventually{} +% +% \DoNotIndex{\def,\edef,\gdef,\xdef,\global,\long,\let} +% \DoNotIndex{\expandafter,\string,\the,\ifx,\else,\fi} +% \DoNotIndex{\csname,\endcsname,\relax,\begingroup,\endgroup} +% \DoNotIndex{\DeclareTextCommand,\DeclareTextCompositeCommand} +% \DoNotIndex{\space,\@empty,\special} +% +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% \section{Introduction} +% +% The word \textbf{\AcroFLeX} is meant to convey a merging of two computer technologies: +% \begin{itemize} +% \item \textbf{Acro}: connotes both \textbf{Adobe Acrobat} (\textbf{Adobe Reader}) +% and \textbf{{Acro\negthinspace\TeX}} (as in the +% \textbf{{Acro\negthinspace\TeX} eDucation Bundle} or, just \textbf{AeB}). +% \item \textbf{F\kern-.1667em\lower.5ex\hbox{L}\kern-.3eme\kern-.125emX\@}: connotes +% \textbf{Adobe FLEX 3}. FLEX 3 is used to create SWF files to interact with the user. +% In the case of graphing, plotting information is passed from Acrobat, via JavaScript, +% to the Flash widget. ActionScript receives the data, plots the points, and +% connects them with a smooth curve or a straight line segment. +% \end{itemize} +% Acrobat 9 Pro introduces the rich media annotation which plays FLV movies +% and SWF files natively. Acrobat also provides a scripting bridge +% between JavaScript for Acrobat, and ActionScript, the scripting +% language of Flash player. This bridge enables the PDF and the +% Flash widget, embedded in the rich media annotation, to communicate. The scripting bridge +% opens up wonderful opportunities for application to the education +% sector. The graphing of {\AcroFLeX} is one such application of the new +% PDF-Flash connection to education. +% +% \textbf{{\AcroFLeX}} uses the commercial product Adobe FLEX Builder~3 and +% FLEX~3 SDK to produce Flash widgets, and the AeB +% to create PDF documents with appropriate JavaScript to communicate +% with the Flash widget. FLEX Builder~3 is currently free for students +% and educators, the FLEX 3 SDK is free to all. +% +% This style file defines some basic controls for +% \textbf{{\AcroFLeX} Graphing} for controlling graphical SWF files +% for graphing. +% +% These commands are general {\LaTeX} commands, that require no special driver, so +% they can be used by, for example, pdftex; however, we use SWF files to produce +% the graphing screen with the built-in ActionScript to communicate with the PDF. +% For this, you will need Acrobat 9 Pro. In that case, you might as well use the +% Acrobat Distiller to produce your PDF, but it is not necessary. +% +% \medskip\noindent +% Let's begin with a declaration of the {\AcroFLeX} logo. +% \begin{macrocode} +\RequirePackage{rmannot}[2016/02/01] +% \end{macrocode} +%\changes{v1.6}{2015/10/13}{Save catcodes of subscript and superscript, both +% of these are used in ordinary characters in the file.} +% Change catcodes of subscript and superscript to other. +% \begin{macrocode} +\edef\af@subscriptCat{\the\catcode`\_} +\edef\af@superscriptCat{\the\catcode`\^} +\def\af@restoreCats{% + \catcode`\_=\af@subscriptCat + \catcode`\^=\af@superscriptCat +} +\catcode`\_=12\relax \catcode`\^=12\relax +\def\AcroFLeX{% + AcroF\kern-.1667em\lower.5ex\hbox{L}\kern-.3eme\kern-.125emX\@} +% \end{macrocode} +% \begin{macro}{\pathToAcroFlex} +% Set the path to {\AcroFLeX} widget, \texttt{AcroFlex.swf}, that actually does the +% graphing. +% \begin{macrocode} +\newcommand{\pathToAcroFlex}[1]{\def\af@pathToAcroFlex{#1}% + \ifx\af@pathToAcroFlex\@empty + \PackageError{acroflex}{% + You must specify a full path to AcroFlex.swf}{}\else + \saveNamedPath{acroflexWidget}{\af@pathToAcroFlex/AcroFlex.swf}\fi +} +\def\af@pathToAcroFlex{} +\@onlypreamble{\pathToAcroFlex} +% \end{macrocode} +% \end{macro} +% \paragraph*{Define package options.} +% \begin{macro}{lang} +% We offer up a single package option, \texttt{lang}. The only languages supported +% at this time are \texttt{english} and \texttt{german}. Additional languages may be supported in the +% future. +% \begin{macrocode} +\define@choicekey*+{acroflex.sty}{lang}[\val\nr]{english,german} +{% + \ifcase\nr\relax + \def\af@lang@type{afcustom_us.def} + \or + \def\af@lang@type{afcustom_de.def} + \else + \def\af@lang@type{afcustom.def} + \fi +}{\PackageWarning{acroflex}{Bad choice for lang, permissible values +are english and german. No lang key is equivalent to english. Try again}} +\def\af@lang@type{afcustom.def} +% \end{macrocode} +% \end{macro} +% \paragraph*{Process the options.} +% We process our meager number of options here. +% \begin{macrocode} +\ProcessOptionsX +% \end{macrocode} +% \paragraph*{Input Configuration File.} At this point, we input the configuration file. The +% major entry, and probably the only entry in this file is the \cs{pathToAcroFlex}. The file +% should contain a line of code like this one: +%\begin{verbatim} +% \pathToAcroFlex{c:/acrotex/aebpro/acroflex/swf} +%\end{verbatim} +% \begin{macrocode} +\InputIfFileExists{acroflex.cfg}{}{} +% \end{macrocode} +% +% \section{Graphing a Single Function} +% +% This section describes the graphing screen and its controls. +% +% \subsection{Some Initial Parameters} +% +% Should you wish to use an {\AcroFLeX} graphic in your PDF, you will need to declare +% several parameters for each graphic: \cs{dimScreenGraph} and \cs{graphName}, +% these are the rich media annotation dimensions, the rich media annot number of this annot +% on this page, and a unique name (unique to the document) for the graph. +% +% You also need to declare a default function, if different from the one set by this package, +% the default domain/range of $x$ and $y$ (the graph view window), and the default domain +% of parameter equations (this last is options if no parametric equations are to be used). +% +% \paragraph{Setting the Dimensions of the Annotation} +% +% \begin{macro}{\dimScreenGraph} +% This is a convenience command for storing the dimensions of the Flash widget. It assumes +% you do not resize using \cs{resizebox} or \cs{scalebox}. The command defines two +% commands available to the document author, these are \cs{hScreenGraph} and +% \cs{vScreenGraph}, for the width and height respectively. +% \begin{macrocode} +\newcommand{\dimScreenGraph}[2]{{% + \setlength{\dimen@}{#1}\xdef\hScreenGraph{\the\dimen@}% + \setlength{\dimen@}{#2}\xdef\vScreenGraph{\the\dimen@}% +}} +% \end{macrocode} +% \end{macro} +% +% \paragraph{Setting the Name of the Graph} +% +% \begin{macro}{\graphName} +% Each graphing screen must have a unique (base)name, the name is specified +% using the command \cs{graphName}; for example \verb!\graphName{mygraph}! +% specifies the base name for the next graphing screen. This name is use +% in creating the control for the graphing screen (a Flash widget). +% +% \begin{macrocode} +\newcommand{\graphName}[1]{\def\afgraphName{#1}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\defaultFunction} +% Declare the default function to appear in the \cs{fileInputField} on startup +% or on reset. The function takes two arguments, the first is a display version of +% the function, the second is a proper JavaScript form of the function. The default +% is \verb!\defaultFunction{x^2}! +% \begin{macrocode} +\newcommand{\defaultFunction}[1]{\def\af@DefaultFunction{#1}} +\defaultFunction{x^2} +% \end{macrocode} +% \end{macro} +% +% \paragraph{Setting the View Screen Dimensions: Range/Domain} +% +% \begin{macro}{\defaultDomRng} +% \begin{macro}{\defaultDomP} +% Set the default domain and range of the default function. These values will appear +% on start-up, and when the graph is cleared. +% \begin{macrocode} +\def\defaultDomRng#1#2#3#4{% + \def\af@DefaultDomMin{#1}\def\af@DefaultDomMax{#2}% + \def\af@DefaultRngMin{#3}\def\af@DefaultRngMax{#4}% +} +\def\defaultDomP#1#2{% + \def\af@DefaultDomMint{#1}\def\af@DefaultDomMaxt{#2}% +} +% \end{macrocode} +% We set the default domain and range to correspond with the +% default function. +% \begin{macrocode} +\defaultDomRng{-2}{2}{0}{4} +\defaultDomP{0}{2*PI} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{The Graphing Screen and its Controls} +% +% Here, we describe the graphing screen and its controls. The graphing screens and +% its controls may be arranged on the page in any way the document author wishes. +% +% \subsubsection{The Graphing Screen} +% +% The graphing screen is the centerpiece of the {\AcroFLeX} graphing system. +% +% \begin{macro}{\graphScreen} +% +% The \cs{graphScreen} command is just the \cs{rmAnnot} command with the +% fourth argument set to the \texttt{acroflexWidget}. The command takes +% three parameters, each just passed to \cs{rmAnnot}: The first is optional +% that sets the key-value pairs, an important one is \texttt{poster=afposter} +% to get the famous \AcroFLeX{} logo inserted as the opster; the second +% is the width; the third is the height. The widget resizes itself, so the choice +% of the dimensions is up to the document author. +% +% If \cs{dimSreenGraph} is used then you can simply use the dimensions declared there; +% for example, +%\begin{verbatim} +% \dimScreenGraph{186bp}{186bp*3/4} +% ... +% \graphScreen[poster=aflogo]{\hScreenGraph}{\vScreenGraph} +%\end{verbatim} +% Note the use of calculated height, three-fourths of the width. \cs{graphScreen} can be, +% in turn, be resized using \cs{resizebox} or \cs{scalebox}. +% +% \begin{macrocode} +\newcommand{\graphScreen}[3][]{\rmAnnot[#1,% + name=afRM\afgraphName]{#2}{#3}{acroflexWidget}}% +% \end{macrocode} +% \end{macro} +% \begin{macro}{\iconFloatGraphScreen} +% Should you wish to create a graphing screen in a floating window, use the +% \cs{iconFloatGraphScreen}. It takes three arguments, the first one is optional +% and is passed to the first argument the underlying \cs{graphScreen}. A typical +% first argument is a poster key value: \texttt{poster=aflogo}. The second two are +% dimensions (width and height). We use \cs{resizebox} from the graphicx package. +% The \cs{resizebox} can take an exclamation point (!) as its arguments, in this +% case, the object will be resized to keep its aspect ratio. See the documentation +% of \cs{resizebox} for more details. Below is an example, +%\begin{verbatim} +% \iconFloatGraphScreen[poster=aflogo]{40bp}{!} +%\end{verbatim} +% The rich media annotation has a transparent button on top of it. The poster of the annotation +% can be see through the button. Pressing on the button activates, or deactivates the annotation. +% +% The default is not to allow the user to close the window or go into full screen mode, however +% by executing\DescribeMacro{\allowFSFloatGS} \cs{allowFSFloatGS} before the +% \cs{iconFloatGraphScreen} command, we allow for full screen, while +% \DescribeMacro{\defaultFloatGS} \cs{defaultFloatGS} returns to the default state. +% \begin{macrocode} +\newcommand{\allowFSFloatGS}{\def\af@passcontext{\@gobble}} +\newcommand{\defaultFloatGS}{\def\af@passcontext{passcontext}} +% \end{macrocode} +% We set the default value, we do no allow full screen. +% \begin{macrocode} +\defaultFloatGS +% \end{macrocode} +% Now for the \cs{iconFloatGraphScreen} command +% \begin{macrocode} +\newcommand{\iconFloatGraphScreen}[3][]{% + \makebox[0pt][l]{% + \resizebox{#2}{#3}{% +% \end{macrocode} +% Here is the graphing screen +% \begin{macrocode} + \graphScreen[#1,windowed,\af@passcontext,deactivated=pageclose + ]{\hScreenGraph}{\vScreenGraph}}}% + \resizebox{#2}{#3}{% +% \end{macrocode} +% And the button that overlays it +% \begin{macrocode} + \pushButton[\S{S}\H{N}\autoCenter{n}\W0\BG{}\BC{} + \TU{\tt@iconFloatGraphScreen}\A{\JS{% + var rm = this.getAnnotRichMedia(% + this.pageNum, "afRM\afgraphName");\r + rm.activated=!rm.activated; + }}]{float\afgraphName Btn-\therm@Cnt}{\hScreenGraph} + {\vScreenGraph}}% +} +\newcommand{\tticonFloatGraphScreen}[1]{% + \def\tt@iconFloatGraphScreen{#1}} +\tticonFloatGraphScreen{Click to view graphing screen, + click again to hide graphing screen.} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Various Controls} +% +% The graphing screen, obviously, graphs functions of the form $ y = f(x) $. The user +% must have a way of entering the functional part, the $f(x)$. \cs{fileInputField} +% is used for this purpose. The \cs{graphBtn} is used to graph the function, while +% \cs{graphClrBtn} is used to clear the graph and deactivate the Flash widget. +% +% The domain of the variable $x$ is specified though the commands +% \cs{domMin} and \cs{domMax}; while the range of values on +% the $y$ axis is specified by \cs{rngMin} and \cs{rngMax}. The number of points +% that are plotted can be specified through \cs{numPoints}. +% +% \paragraph{The Input Function.} +% \begin{macro}{\funcInputField} +% The parameters for all the above mentioned functions, with the exception of +% \cs{afDefaultFunction}, take three parameters generally described below: +% +% \begin{enumerate} +% \item[\texttt{[\#1]}:] optional arguments to modify appearance of the form field +% \item[\texttt{\#2}:] the width of the form field +% \item[\texttt{\#3}:] the height of the form field +% \end{enumerate} +% The definitions below use two new keys, \cs{nuDV} and \cs{nuV}, to avoid the use +% of unicode when the unicode option of hyperref has been invoked. The initial and +% default values of the function input field may contain symbols like \texttt{\string^} +% that hyperref does not like and strips out. These two keys are also used in +% \cs{functionSelect} below, for the same reason. +% \begin{macrocode} +\newcommand{\funcInputField}[3][]{\makebox[0pt][l]{% + \textField[% + \nuDV{\af@DefaultFunction}\nuV{\af@DefaultFunction} + \F{\FHidden}\Ff{\FfReadOnly} + ]{\afgraphName theHiddenFunction}{1bp}{1bp}}% + \textField[% + \BC{0 0 0}\nuDV{\af@DefaultFunction}\nuV{\af@DefaultFunction} + \TU{\tt@funcInputField}#1\AA{\AAFormat{% + \formatFunctionInput{"\afgraphName theHiddenFunction"}} + \AAKeystroke{\keystrokeFunctionInput} + }% + ]{\afgraphName theFunction}{#2}{#3}% +} +\newcommand{\ttfuncInputField}[1]{% + \def\tt@funcInputField{#1}} +\ttfuncInputField{Enter any of the following for expressions:\r +\space\space1. A function of x of the form f(x);\r +\space\space2. A polar function of t of the form f(t);\r +\space\space3. A set of parametric functions of t of the form f(t);g(t) +\r\space\space\space\space\space(separated by a semi-colon);\r +\space\space4. A list of points, (a1,b1);(a2,b2);...;(an,bn)\r +\space\space\space\space\space(separated by semi-colons). +} +% \end{macrocode} +% I originally named the previous macro definition \cs{fileInputField}. My bad! +% In case there is someone out there that uses this package, I'll let +% \cs{fileInputField} to \cs{funcInputField}. +% \begin{macrocode} +\let\fileInputField\funcInputField +% \end{macrocode} +% \end{macro} +% \begin{macro}{\formatFunctionInput} +% \cs{formatFunctionInput} supplies format event for the +% \cs{funcInputField}. Then the user enters a new function, the JavaScript function +% \texttt{formatFunctionInput} executes \texttt{ParseInput} (from \textsf{exerquiz}), and places it +% in the hidden function field. +% \begin{macrocode} +\def\formatFunctionInput#1{% + try{ formatFunctionInput(#1) } catch(e){}; +} +\def\keystrokeFunctionInput{% + try{ keystrokeFunctionInput() } catch(e){}; +} +% \end{macrocode} +% \end{macro} +% \paragraph{The Curve Select Combo Box.} +% \begin{macro}{\functionSelect} +% \begin{macro}{\initFuncSelect} +% \begin{macro}{\savedelSelBtn} +% This is an optional combo box for selecting curves and points to graph. +% Note, this drop down list should not overlay the graphing widget, the widget +% is on top, and the list cannot be seen. +% \begin{macrocode} +\newcommand{\afCurve}[1]{\def\afcurve{#1 }\def\afcurvei{#1}} +\afCurve{Curve} +\newcommand{\afPoint}[1]{\def\afpoint{#1 }\def\afploti{#1}} +\afPoint{Point} +\newcommand{\afUnused}[1]{\def\afunused{#1}} +\afUnused{--unused} +% \end{macrocode} +% Any re-definitions should take place in the preamble only! +% \begin{macrocode} +\@onlypreamble\afCurve +\@onlypreamble\afPoint +\@onlypreamble\afUnused +% \end{macrocode} +% The listing of the drop-down menu. To begin with, there are eight +% menu items: four for curves, and four for plotted points. +% \begin{macrocode} +\newcommand{\initFuncSelect}[1]{\def\af@initializeFuncSelect{#1}} +\initFuncSelect{% + [(\af@DefaultFunction)(\afcurve1)]% + [(<\afcurve2\afunused>)(\afcurve2)]% + [(<\afcurve3\afunused>)(\afcurve3)]% + [(<\afcurve4\afunused>)(\afcurve4)]% + [(<\afpoint1\afunused>)(\afpoint1)]% + [(<\afpoint2\afunused>)(\afpoint2)]% + [(<\afpoint3\afunused>)(\afpoint3)]% + [(<\afpoint4\afunused>)(\afpoint4)]} +% \end{macrocode} +% The combo box that displays the above items. On selection, +% we populate the \texttt{theFunction} field. +% \begin{macrocode} +\newcommand{\functionSelect}[3][]{% + \comboBox[\TU{\tt@functionSelect}#1\Ff{\FfCommitOnSelChange} + \nuDV{\af@DefaultFunction}\nuV{\af@DefaultFunction} + \AA{\AAKeystroke{% + if (!event.willCommit) {\r\t + this.getField( + "\afgraphName theFunction").value=event.changeEx;\r + }}}]{\afgraphName ComboSelect}{#2}{#3}{\af@initializeFuncSelect}% +} +\newcommand{\ttfunctionSelect}[1]{% + \def\tt@functionSelect{#1}} +\ttfunctionSelect{Enter a function on \afcurvei1--\afcurvei4, or + a list of points on \afploti1--\afploti4.} +% \end{macrocode} +% Saves the current function to the list, shift-click deletes +% the current list item, and returns it to its default. +% \begin{macrocode} +\newcommand{\savedelSelBtn}[3][]{% + \pushButton[\TU{\tt@savedelSelBtn}#1 + \A{\JS{saveDelSelAction("\afgraphName"); + }}]{\afgraphName savedelSelectBtn}{#2}{#3}% +} +\newcommand{\ttsavedelSelBtn}[1]{\def\tt@savedelSelBtn{#1}} +\ttsavedelSelBtn{Click to save current function to list, shift-click + to delete the current function from list} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \paragraph{The Graphing Button.} +% \begin{macro}{\graphBtn} +% Clicking on this button when the +% rich media annot is not activated will activate it. Clicking on +% this button when the rich media annot is activate will cause the +% function in the \cs{fileInputField} to be graphed. +% \begin{macrocode} +\newcommand{\graphBtn}[3][]{% + \pushButton + [\BC{0 0 0}\CA{Graph It!}\TU{\tt@graphBtn}#1 + \A{\JS{graphBtnAction("\afgraphName",this.pageNum); + }}]{\afgraphName graphIt}{#2}{#3}% +} +\newcommand{\ttgraphBtn}[1]{\def\tt@graphBtn{#1}} +\ttgraphBtn{Press to graph the function} +% \end{macrocode} +% \end{macro} +% \paragraph{The Clear Screen Button.} +% +% \begin{macro}{\graphClrBtn} +% \begin{macro}{\clearGraphJS} +% Click on this button and all fields +% associated with this graphing screen are reset. Shift click makes the +% AcroFlex widget deactivated. +% \begin{macrocode} +\newcommand{\clearGraphJS}{% + clearGraph("all","\afgraphName",this.pageNum);} +\newcommand{\graphClrBtn}[3][]{\pushButton[\BC{0 0 0}\CA{Clear} + \A{\JS{\clearGraphJS}}\TU{\tt@graphClrBtn}#1 + ]{\afgraphName clearIt}{#2}{#3}% +} +\newcommand{\ttgraphClrBtn}[1]{\def\tt@graphClrBtn{#1}} +\ttgraphClrBtn{Click to clear graph, shift-click to deactivate the + graphing screen} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \paragraph{The Domain the function is to be graphed over.} +% +% \begin{macro}{\domMin} +% \begin{macro}{\domMax} +% The lower endpoint of the interval over which the function is +% graphed. +% +% \begin{macrocode} +\newcommand{\domMin}[3][]{\makebox[0pt][l]{% + \textField[\nuDV{\af@DefaultDomMin}\nuV{\af@DefaultDomMin} + \F{\FHidden}\Ff{\FfReadOnly} + ]{\afgraphName theHiddenDom.min}{1bp}{1bp}}% + \textField[\textSize{0}\nuV{\af@DefaultDomMin} + \nuDV{\af@DefaultDomMin}\BC{0 0 0}\TU{\tt@domMin}#1\AA{% + \AAKeystroke{\keystrokeDomRng{"\afgraphName theHiddenDom.min"}} + \AAFormat{\formatVarIntervals{"\afgraphName theHiddenDom.min"}} + }]{\afgraphName theDom.min}{#2}{#3}% +} +\newcommand{\ttdomMin}[1]{\def\tt@domMin{#1}} +\ttdomMin{Enter the minimum value for the variable x} +% \end{macrocode} +% The upper endpoint of the interval over which the function is graphed. +% \begin{macrocode} +\newcommand{\domMax}[3][]{\makebox[0pt][l]{% + \textField[\nuDV{\af@DefaultDomMax}\nuV{\af@DefaultDomMax} + \F{\FHidden}\Ff{\FfReadOnly} + ]{\afgraphName theHiddenDom.max}{1bp}{1bp}}% + \textField[\textSize{0}\nuV{\af@DefaultDomMax} + \nuDV{\af@DefaultDomMax}\BC{0 0 0}\TU{\tt@domMax}#1\AA{% + \AAKeystroke{\keystrokeDomRng{"\afgraphName theHiddenDom.max"}} + \AAFormat{\formatVarIntervals{"\afgraphName theHiddenDom.max"}} + }]{\afgraphName theDom.max}{#2}{#3}% +} +\newcommand{\ttdomMax}[1]{\def\tt@domMax{#1}} +\ttdomMax{Enter the maximum value for the variable x} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \paragraph{The interval on vertical axis what is to be displayed.} +% \begin{macro}{\rngMin} +% \begin{macro}{\rngMax} +% The lower endpoint of the interval on the $y$-axis that is displayed on the +% graphing screen. +% \begin{macrocode} +\newcommand{\rngMin}[3][]{\makebox[0pt][l]{% + \textField[\nuDV{\af@DefaultRngMin}\nuV{\af@DefaultRngMin} + \F{\FHidden}\Ff{\FfReadOnly} + ]{\afgraphName theHiddenRng.min}{1bp}{1bp}}% + \textField[\textSize{0}\nuV{\af@DefaultRngMin} + \nuDV{\af@DefaultRngMin}\BC{0 0 0}\TU{\tt@rngMin}#1\AA{% + \AAKeystroke{\keystrokeDomRng{"\afgraphName theHiddenRng.min"}} + \AAFormat{\formatVarIntervals{"\afgraphName theHiddenRng.min"}} + }]{\afgraphName theRng.min}{#2}{#3}% +} +\newcommand{\ttrngMin}[1]{\def\tt@rngMin{#1}} +\ttrngMin{Enter the minimum value for the variable y} +% \end{macrocode} +% The upper endpoint of the interval on the $y$-axis that is displayed on the +% graphing screen. +% \begin{macrocode} +\newcommand{\rngMax}[3][]{\makebox[0pt][l]{% + \textField[\nuDV{\af@DefaultRngMax}\nuV{\af@DefaultRngMax} + \F{\FHidden}\Ff{\FfReadOnly} + ]{\afgraphName theHiddenRng.max}{1bp}{1bp}}% + \textField[\textSize{0}\nuV{\af@DefaultRngMax} + \nuDV{\af@DefaultRngMax}\BC{0 0 0}\TU{\tt@rngMax}#1\AA{% + \AAKeystroke{\keystrokeDomRng{"\afgraphName theHiddenRng.max"}} + \AAFormat{\formatVarIntervals{"\afgraphName theHiddenRng.max"}} + }]{\afgraphName theRng.max}{#2}{#3}% +} +\newcommand{\ttrngMax}[1]{\def\tt@rngMax{#1}} +\ttrngMax{Enter the maximum value for the variable y} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \paragraph{The Domain parametric equations is to be graphed over.} +% \begin{macro}{\domMinP} +% \begin{macro}{\domMaxP} +% The lower endpoint of the interval over which the function is graphed. +% \begin{macrocode} +\newcommand{\domMinP}[3][]{\makebox[0pt][l]{% + \textField[\nuDV{\af@DefaultDomMint}\nuV{\af@DefaultDomMint} + \F{\FHidden}\Ff{\FfReadOnly} + ]{\afgraphName theHiddenDom_t.min}{1bp}{1bp}}% + \textField[\textSize{0}\nuV{\af@DefaultDomMint} + \nuDV{\af@DefaultDomMint}\BC{0 0 0}\TU{\tt@domMinP}#1\AA{% + \AAKeystroke{\keystrokeDomRng{"\afgraphName theHiddenDom_t.min"}} + \AAFormat{\formatVarIntervals{"\afgraphName theHiddenDom_t.min"}} + }]{\afgraphName theDom_t.min}{#2}{#3}% +} +\newcommand{\ttdomMinP}[1]{\def\tt@domMinP{#1}} +\ttdomMinP{Enter the minimum value for the variable t} +% \end{macrocode} +% The upper endpoint of the interval over which the function is graphed. +% \begin{macrocode} +\newcommand{\domMaxP}[3][]{\makebox[0pt][l]{% + \textField[\nuDV{\af@DefaultDomMaxt}\nuV{\af@DefaultDomMaxt} + \F{\FHidden}\Ff{\FfReadOnly} + ]{\afgraphName theHiddenDom_t.max}{1bp}{1bp}}% + \textField[\textSize{0}\nuV{\af@DefaultDomMaxt} + \nuDV{\af@DefaultDomMaxt}\BC{0 0 0}\TU{\tt@domMaxP}#1\AA{% + \AAKeystroke{\keystrokeDomRng{"\afgraphName theHiddenDom_t.max"}} + \AAFormat{\formatVarIntervals{"\afgraphName theHiddenDom_t.max"}} + }]{\afgraphName theDom_t.max}{#2}{#3}% +} +\newcommand{\ttdomMaxP}[1]{\def\tt@domMaxP{#1}} +\ttdomMaxP{Enter the maximum value for the variable t} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\formatVarIntervals} +% \begin{macro}{\keystrokeDomRng} +% These are format and keystroke functions that support the above +% domain and range commands. +% \begin{macrocode} +\def\formatVarIntervals#1{% + try{ formatVarIntervals(#1) } catch(e){}; +} +\def\keystrokeDomRng#1{% + if (event.willCommit) keystrokeDomRng(#1); +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \paragraph{The Number of points to plot.} +% \begin{macro}{\numPoints} +% \begin{macro}{\defaultNumPoints} +% The number of points to use for plotting the specified function. +% \begin{macrocode} +\newcommand{\defaultNumPoints}[1]{% + \def\af@defaultNumPoints{#1}} +\defaultNumPoints{40} +\newcommand\numPoints[3][]{% + \textField[\nuV{\af@defaultNumPoints}\nuDV{\af@defaultNumPoints} + \Q1\BC{0 0 0}\TU{\tt@numPoints}#1\AA{% + \AAKeystroke{if (event.willCommit) keystrokeNumPoints();}} + ]{\afgraphName numNodes}{#2}{#3}% +} +\newcommand{\ttnumPoints}[1]{\def\tt@numPoints{#1}} +\ttnumPoints{Enter the number of points to plot} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \paragraph{Shifting the Graph Screen.} +% In this section we provide basic control for shifting the graph screen up and down, +% and left and right. Two new text fields are designed to set the amount of vertical +% or horizontal shifting. +% +% \begin{macro}{\amtShift} +% Use this text field to enter the amount of horizontal or vertical shift. +% +% We have the usual three parameters, optional argument to change the appearance, +% the width of the form field, the height of the form field. +% \begin{macrocode} +\newcommand{\defaultShiftAmt}[1]{% + \def\af@defaultShiftAmt{#1}} +\defaultShiftAmt{1} +\newcommand{\amtShift}[3][]{% + \textField[\nuV{\af@defaultShiftAmt}\nuDV{\af@defaultShiftAmt}\Q1 + \BC{0 0 0}\TU{\tt@amtShift}#1\AA{\AAKeystroke{% + if (event.willCommit) keystrokeAmtShift(); + }}]{\afgraphName amtshift}{#2}{#3}% +} +\newcommand{\ttamtShift}[1]{\def\tt@amtShift{#1}} +\ttamtShift{Enter the amount to shift, horizontally or vertically} +% \end{macrocode} +% \end{macro} +% +% For the controls for initiating the shifting action, we can use forms or links. We'll begin +% by using links. +% \begin{macro}{\hShiftL} +% \begin{macro}{\hShiftR} +% \begin{macro}{\vShiftD} +% \begin{macro}{\vShiftU} +% Basic link to initiate the actions of shifting the viewing screen horizontally or vertically +% an amount equal to the entries in \cs{amtShift}. +% \begin{macrocode} +\newcommand{\hShiftL}[2][]{% + \setLinkText[#1\A{\JS{% + shiftHorVert ("\afgraphName",this.pageNum,"h","-"); + }}]{#2}% +} +\newcommand{\hShiftR}[2][]{% + \setLinkText[#1\A{\JS{% + shiftHorVert ("\afgraphName",this.pageNum,"h","+"); + }}]{#2}% +} +\newcommand{\vShiftD}[2][]{% + \setLinkText[#1\A{\JS{% + shiftHorVert ("\afgraphName",this.pageNum,"v","-"); + }}]{#2}% +} +\newcommand{\vShiftU}[2][]{% + \setLinkText[#1\A{\JS{% + shiftHorVert ("\afgraphName",this.pageNum,"v","+"); + }}]{#2}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \paragraph{The Zooming in and out.} +% Coming fresh off the success of the horizontal and vertical shifting commands, let's plough +% on to zooming in. +% \begin{macro}{\zoomInOut} +% This push button control zooms out, with a click, or zoom in with a shift-click. +% \begin{macrocode} +\newcommand{\zoomInOut}[3][]{% + \pushButton[\BC{0 0 0}\CA{Zoom}\TU{\tt@zoomInOut}#1 + \A{\JS{% + var shiftType = (event.shift) ? "+" : "-";\r + zoomInOut ("\afgraphName",this.pageNum,shiftType); + }} + ]{\afgraphName zoominout}{#2}{#3}% +} +\newcommand{\ttzoomInOut}[1]{\def\tt@zoomInOut{#1}} +\ttzoomInOut{Click to zoom out, shift-click to zoom in} +% \end{macrocode} +% \end{macro} +% +% \subsection{Non-Interactive Graphing} +% +% Use the \cs{setLinkText} command to pass a function name, the number of points, and domain/range +% information to the graphing screen, without user input. This command is useful for tutorials +% that would like to create a graph for the student to inspect, or as part of a quiz. +% \begin{macro}{\sgraphLink} +% The command \cs{sgraphLink} has four arguments, the first one is an optional argument +% to modify the appearance of the link; the second argument consist of key-value pairs that +% are options for the {\AcroFLeX} Graphing system; the third argument is the function of the +% semi-colon delimited list of points to be plotted; the fourth argument is the text to be used +% as the link. +%\begin{verbatim} +% \sgraphLink[<appearance>]{<graph_key_vals>}{func|points}{<text>} +%\end{verbatim} +%\paragraph{Options for the Second Parameter.} We define and briefly discuss +% a series of keys for the second parameter. +% +% \begin{macrocode} +% \end{macrocode} +% \DescribeMacro{graph} +% Curves and points are graphed on chart series. This system uses \texttt{LinearSeries}, +% \texttt{PlotSeries}, and \texttt{AreaSeries}. The {\AcroFLeX} graphing widget provides +% four series for each of these three. Values of \texttt{c1}, \texttt{c2}, \texttt{c3}, \texttt{c4} for this key graphs the data +% on a \texttt{LinearSeries}; values of \texttt{p1}, \texttt{p2}, \texttt{p3}, \texttt{p4} plot the data on a \texttt{PlotSeries}; +% and values of \texttt{a1}, \texttt{a2}, \texttt{a3}, \texttt{a4} graphs the data on a \texttt{AreaSeries}. +% \begin{macrocode} +\define@choicekey+{afsl}{graph}{c1,c2,c3,c4,p1,p2,p3,p4,% + a1,a2,a3,a4}[c1]{\edef\afsl@graph{#1}}{\PackageWarning{acroflex} + {Bad choice for the graph key, permissible values are + c1, c2, c3,c4, p1, p2, p3, p4, a1, a2, a3, a4. Try again}} +% \end{macrocode} +% \DescribeMacro{type} +% The type of curve this is, \texttt{cart} ($y=f(x)$), \texttt{para} +% ($x=f(t); y=g(t)$), or \texttt{polar} ($r = f(t)$). When defining a polar function +% using \cs{sgraphLink}, use \texttt{type=polar} to signal that the curve is a polar function. +% \changes{v1.6c}{2016/08/29}{Set defaults for type and connectwith} +% \begin{macrocode} +\define@choicekey+{afsl}{type}{cart,para,polar}[cart]{% + \edef\afsl@type{#1}}{\PackageWarning{acroflex} + {Bad choice for the type key, permissible values are + cart, para, and polar. Try again}} +\let\afsl@type\@empty +% \end{macrocode} +% \DescribeMacro{connectwith} +% When the graph is either a \texttt{LinearSeries} or an +% \texttt{AreaSeries}, the points are connected. Use this key to +% specify how the points are to be connected. The default values +% for this key are as follows: for +% \texttt{graph=cart} it is \texttt{connectwith=curve}, and for +% \texttt{graph=para} it is \texttt{connectwith=segment}. +% Use this key to override these defaults. For parametric equations, +% \texttt{connectwith=curve} is not recommended, the results may not +% be good. Use of this key is recommended for \texttt{graph=cart}. +% \begin{macrocode} +\define@choicekey+{afsl}{connectwith}{curve,segment}[curve]{% + \edef\afsl@form{#1}}{\PackageWarning{acroflex} + {Bad choice for the connectwith key, permissible values are + curve and segment. Try again}} +\let\afsl@form\@empty +% \end{macrocode} +% \DescribeMacro{noquotes} +% This key is a workaround for the case when the function or data is passed by +% JavaScript. Used when passing things that are already strings, such as \texttt{event.value}. +% An example of usage can be found in \texttt{afgraph.tex}. +% \begin{macrocode} +\define@choicekey+{afsl}{noquotes}[\val\nr]{true,false}[true]{% + \ifcase\nr\relax\def\af@quotes{}\or\def\af@quotes{"}\fi} + {\PackageWarning{acroflex} + {Bad choice for the noquotes key, permissible values are + true and false. Try again}} +% \end{macrocode} +% \DescribeMacro{points} +% Use this key to specify the number of points to generate from the function. +% The key is ignored if \texttt{PlotSeries} is used, and should not appear, or be set to zero. +% \begin{macrocode} +\define@key{afsl}{points}[0]{\edef\afsl@nPoints{#1}} +% \end{macrocode} +% \DescribeMacro{xInterval} +% An interval of numbers on the horizontal axis. This interval determines the +% domain over which the function of $x$ is to be graphed. The endpoints of this +% interval also determine the left and right boundaries of the viewing window. +% \begin{macrocode} +\define@key{afsl}{xInterval}[]{\edef\afsl@xInterval{#1}} +% \end{macrocode} +% \DescribeMacro{xPlot} +% (10/11/09) Added the \texttt{xPlot} key. With the \texttt{xInterval} key, the interval over which to +% plot the curve is bound to the scaling on the x-axis. It is now desired to plot +% a graph over a smaller interval than the one on the x-axis, and \texttt{xPlot} will be used for +% that purpose; thus one can say \verb!xInterval={[-2,2]},xPlot={[-1,0]}!. If \texttt{xPlot} +% is not specified, then $\texttt{xPlot}=\texttt{xInterval}$. +% \begin{macrocode} +\define@key{afsl}{xPlot}[]{\edef\afsl@xPlot{#1}} +% \end{macrocode} +% \DescribeMacro{yInterval} +% An interval of numbers on the vertical axis. The endpoints of this +% interval also determine the lower and upper boundaries of the viewing window. +% \begin{macrocode} +\define@key{afsl}{yInterval}[]{\edef\afsl@yInterval{#1}} +% \end{macrocode} +% \DescribeMacro{tInterval} +% An interval of numbers on the parameter axis. This interval determines the +% domain over which a polar function and parametric equations are to be graphed. +% \texttt{xInterval} and \texttt{yInterval} determines the viewing window. +% \begin{macrocode} +\define@key{afsl}{tInterval}[]{\edef\afsl@tInterval{#1}} +% \end{macrocode} +% \DescribeMacro{populate} +% A Boolean value, which if \texttt{true}, signals \texttt{Graph\_xy()} or +% \texttt{Graph\_xyt()} to populate the interactive field controls. When +% no controls are provided for the graphing screen, populate should have a +% value of \texttt{false}. +% \begin{macrocode} +\define@choicekey+{afsl}{populate}{true,false}[true]{% + \edef\afsl@populate{#1}}{\PackageWarning{acroflex} + {Bad choice for the populate key, permissible values are + true and false. Try again}} +% \end{macrocode} +% \DescribeMacro{wait} +% When using \cs{defineGraphJS} to create an action with multiple graph events, +% use \texttt{wait=true}. This setting gives the {\AcroFLeX} graphing widget to +% receive one set of plotting data before trying to digest another. +% \begin{macrocode} +\define@choicekey+{afsl}{wait}{true,false}[true]{% + \edef\afsl@wait{#1}}{\PackageWarning{acroflex} + {Bad choice for the wait key, permissible values are + true and false. Try again}} +% \end{macrocode} +% \paragraph*{Set the defaults for all the keys.} +% All changes are local to each link, so we set global defaults whose values +% are not changed by the changes as a result of the passing key-value pairs +% through \cs{sgraphLink}. +% \begin{macrocode} +\setkeys{afsl}{graph,points,xInterval,xPlot,yInterval,tInterval,% + populate=false,type,connectwith,noquotes=false,wait=false} +% \end{macrocode} +% \begin{macro}{\sgraphLink} +% We finally come to the \cs{sgraphLink}. +% \begin{macrocode} +\newcommand{\sgraphLink}[4][]{{% + \defineGraphJS{#2}{#3}{\af@sglnkAction}% + \setLinkText[#1\A{\JS{\af@sglnkAction}}]{#4}% +}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\defineGraphJS} +% The \cs{defineGraphJS} is the JS used to call the \texttt{Graph\_xy()} or \texttt{Graph\_xyt()} +% JavaScript function defined in this package. It uses the same key-value pairs as the second +% argument of \cs{sgraphLink}. The command can be used to construct links that graph several +% curves (or plots) with a link or form action. It can be integrated into the exerquiz quizzing system, +% using the new key \cs{AddAAKeystroke} of \cs{RespBoxMath}. The use of this key and this command is illustrated +% in the \texttt{acroflex.tex} demo file. +%\par\medskip\noindent +% The \texttt* optional first parameter signals to use \cs{edef} in the subsequent command +% \cs{af@defineGraphJS}. +% \begin{macrocode} +\newcommand{\defineGraphJS}{\@ifstar{\let\AF@exDEF\edef\af@defineGraphJS} + {\let\AF@exDEF\xdef\af@defineGraphJS}} +% \end{macrocode} +% We continue \cs{defineGraphJS}: The first parameter are key-values of the +% \texttt{afsl} family; the second parameter is the function; the third is the +% name to assign the command being defined. +% modify the appearance of the link; the second parameter +% \begin{macrocode} +\newcommand{\af@defineGraphJS}[3]{{\makeJSspecials + \edef\af@tmp@exp{\noexpand\setkeys{afsl}{#1}}\af@tmp@exp + \ifx\afsl@xPlot\@empty\let\afsl@xPlot\afsl@xInterval\fi + \AF@exDEF#3{Graph_xytJS (\af@quotes#2\af@quotes,"\afsl@xInterval",% + "\afsl@yInterval","\afsl@xPlot","\afsl@tInterval","\afsl@graph",% + \afsl@populate,\afsl@wait,"\afsl@type","\afsl@form","\afgraphName",% + \afsl@nPoints)}% +}} +% \end{macrocode} +% \end{macro} +% +% \section{Document JS in Support of \texorpdfstring{\protect\AcroFLeX}{AcroFleX}} +% +% Below are some text macros used in creating error messages. They may be redefined +% into better English, or another language. Use the definition file \texttt{afcustom.def} +% to make these re-definitions. +% \begin{macrocode} +\defineJSStr{\af@badNumberMsg}{% + The value input does not appear to be a number, please enter a + number, or an expression that evaluates to a number.} +\defineJSStr{\af@negNumberMsg}{% + The number of points is a positive integer, changing to a + positive integer.} +\defineJSStr{\af@zeroNumberMsg}{% + The number of points is a positive integer, changing to the + default value of \af@defaultNumPoints.} +\defineJSStr{\af@negShiftMsg}{% + The amount of shift is a positive number, changing to a positive + number.} +\defineJSStr{\af@zeroShiftMsg}{% + The amount of shift is a positive number, changing to the + default value of 1.} +\defineJSStr{\af@saveDelSelAlerti}{% + There is nothing in the function input text field.} +\defineJSStr{\af@saveDelSelAlertii}{% + You have not defined any points to plot} +\defineJSStr{\af@graphBtnAlerti}{Undefined graph types} +% \end{macrocode} +% \begin{macrocode} +\begin{insDLJS*}[acroflexLoaded]{afgrfJS} +\begin{newsegment}{AF: AcroFLeX Graphing Bundle} +/* + Document Level JavaScript + AcroFLeX Graphing Bundle + D. P. Story copyright 2008-\the\year +*/ +var acroflexLoaded = true; +var _mathVars="xt"; +var aGraphData = new Array(); +var ck4PtsRe = /\(.+,.+\)/; +var badNumberMsg=\af@badNumberMsg; +var negNumberMsg=\af@negNumberMsg; +var zeroNumberMsg=\af@zeroNumberMsg; +var negShiftMsg=\af@negShiftMsg; +var zeroShiftMsg=\af@zeroShiftMsg; +var saveDelSelAlerti=\af@saveDelSelAlerti; +var saveDelSelAlertii=\af@saveDelSelAlertii; +var graphBtnAlerti=\af@graphBtnAlerti; +var scratchCounter=0; +var aTimeOutArray = new Array(); +var afSuffixes = new Array("ComboSelect","theFunction", + "amtShift","theDom","theRng", "theDom_t", + "Rng_t","numNodes"); +\end{newsegment} +\begin{newsegment}{AF: Graphing Functions} +% \end{macrocode} +% \DescribeMacro{Graph\_xy} Graphs a function of a single variable in the rectangular +% coordinate system. +% +% The \texttt{Graph\_xy} function takes four or more arguments. In interactive +% mode, it takes four. +%\begin{enumerate} +% \item \texttt{graph\_props}: (Needs Revision) This is a signal for the type of graphing requested. +% \texttt{c1,...,c4} for continuous plotting; and \texttt{p1,...,p4} for discrete +% plotting. There are four of these types. +% \item \texttt{baseName}: The base name of the graphing environment. This is used to +% build the field names for the controls, if any, on the page. +% \item \texttt{pNum}: The page number of the target rich media annot. This together +% with \texttt{baseName} is enough information to get the AnnotRichMedia object using +% the \texttt{Doc.AnnotRichMedia} method. +%\end{enumerate} +% When in interactive mode, we get the function to be graphed, the domain of $x$ +% the range of $y$, and the number of points to plot from form fields. +% \begin{itemize} +% \item The function is input by the user into the field \texttt{baseName+"theFunction"}, +% but we get the JS version from \texttt{baseName+"theHiddenFunction"}. +% When the user enters a function, it is parsed, and changed into a proper JS +% expression: \verb!2x^2sin(x)! becomes \verb!2*Math.pow(x,2)*Math.sin(x)!. +% +% \item The domain and range values are input by the user through the fields, having field names of +% \texttt{baseName+"theDom.min"}, \texttt{baseName+"theDom.max"}, \texttt{baseName+"theRng.min"}, +% and \texttt{baseName+"theRng.max"}, but we retrieve the values from hidden fields. +% See \texttt{getDomRng} below for the listing of the hidden fields. +% When the user enters domain/range info, this info is parsed and made into +% property JS expressions. In this way, the user can enter symbolics like \texttt{PI} +% or \texttt{sin(PI/3)}, or do arithmetic, like \texttt{2 + 1/3}. +% +% \item The number of points to plot is obtained from \texttt{baseName+"numNodes"}, +% no preprocessing is used. +% +% \end{itemize} +% +% \noindent When the number of arguments is greater than four, we are in non-interactive +% mode. The 5th argument is the JS function to graph; the 6th is the number of +% points to plot; the 7th is an object containing the domain +% +% \paragraph{Notes on the Modes.} There are three modes of operation: interactive, populate, +% and silent. +%\begin{itemize} +% \item \textbf{Interactive:} This occurs when the user enters a +% function through the UI. In this case the number of arguments +% passed to \texttt{Graph\_xy} (or \texttt{Graph\_xyt}) is only four. +% The number of \texttt{arguments} is determined by the arguments +% object, and the switch \texttt{afInteractive} is set to +% \texttt{true}. For this mode +% +% The following controls are \emph{required}: \cs{fileInputField}, +% \cs{graphBtn}, \cs{domMin}, \cs{domMax}, \cs{rngMin}, \cs{rngMax}, +% and \cs{numPoints}. If parametric or polar graphs are to be used, +% then \cs{domMinP} and \cs{domMaxP} are also required. The other +% controls are \emph{optional}, \cs{graphClrBtn} (recommended), +% \cs{amtShift} (and \cs{hShiftL}, +% \cs{hShiftR},\cs{vShiftD},\cs{vShiftU}) and \cs{zoomInOut}. +% +% \item \textbf{Populate:} This mode occurs when the graphing parameters +% are passed to \texttt{Graph\_xy} (or \texttt{Graph\_xyt}) by \cs{sgraphLink} +% (or some other command). All the essential information is passed as arguments, +% so the number of arguments is greater than four. The command initiating the +% graphing should set the \texttt{graph\_props.populate} to \texttt{true}. In this +% case the graphing data populate the required fields and the graph will be drawn. +% It is the document author's responsibility to only use populate on graphing screens +% that have all the required control fields. \texttt{Graph\_xy} (and \texttt{Graph\_xyt}) +% checks the value of the \texttt{graph\_props.populate} property, and sets the switch +% \texttt{populate} to \texttt{true}. +% +% Populate behave exactly like interactive, but the graphing data is passed to it in pre-packaged +% for my the document author; the user, however, can manipulate the curve once it appears. +% +% The required controls are the same as the interactive mode. +% +% \item \textbf{Silent:} This is a non-interactive mode, there must be no controls other than +% \cs{graphClrBtn}. Basically, the author prepares some pre-packaged graphs to be displayed +% to the user, without interaction. These may go along with a tutorial discussion symmetry, +% periodicity, tangent lines, etc. +% +%\end{itemize} +% \begin{macrocode} +function Graph_xy(graph_props, baseName, pNum) +{ + _mathVars="x"; + var afInteractive = (arguments.length <= 3); + if (afInteractive) { + var f = this.getField(baseName+"theHiddenFunction").value; +% \end{macrocode} +% If the file input field does not contain a Cartestian point $(a,b)$, +% but it does contain a semi-colon, we figure what is entered is a +% set of parametric equations. +% \begin{macrocode} + if ( !ck4PtsRe.test(f) && (f.indexOf(";")!=-1) ) { + var dt = this.getField(baseName+"theDom_t.min"); + if ( dt == null ) { + syntaxError(); return; + } + Graph_xyt(graph_props, baseName, pNum); + return; + } + f = this.getField(baseName+"theHiddenFunction").value; + } + createGraphData(baseName); + var which_graph=graph_props.graph; + var populate = false; + graph_props.type="cart"; + var aWhichGraph=/(c|p|a)(\d)/.exec(which_graph); + if ( aWhichGraph==null ) aWhichGraph=["","c","1"]; + var isGraph = (aWhichGraph[1]=="c" || aWhichGraph[1]=="a"); + var connectPoints=false; + var plotPoints=false; + var wait = false; + switch(aWhichGraph[1]) { + case "p": + var which_series="p"+aWhichGraph[2]; + plotPoints=true; + break; + case "a": + var which_series="a"+aWhichGraph[2]; + break; + default: + var which_series="c"+aWhichGraph[2]; + } + graph_props.graph=which_series; +% \end{macrocode} +% Get domain and range of x and y, respectively +% obtain in math environment so we can evaluate +% any symbolic constants, such as \texttt{Math.PI} +% \begin{macrocode} + if (afInteractive) var oDR = getDomRng (baseName); + else { + wait=graph_props.wait; + populate = graph_props.populate; + var oDR = arguments[5]; + if (populate) populateDomRng(baseName,oDR); + for ( var o in oDR ) oDR[o] = EvalParse(oDR[o]); + } + aGraphData[baseName].aDomRngs = oDR; +% \end{macrocode} +% calculate width of intervals. If the user has passed a subinterval to us, then +% \texttt{oDR.x\_min} would be defined, and we use it to compute the range. +% \begin{macrocode} + var rng_x = (typeof oDR.x_u=="undefined") ? + (oDR.x_max - oDR.x_min) : (oDR.x_u - oDR.x_l); + /* Get the function and calculated the plotted points */ + if (afInteractive) { + var n = Number(this.getField(baseName+"numNodes").value); + if ( isNaN(n) || n <=0 ) n = \af@defaultNumPoints; + } else { + var f = ParseInput(arguments[2+1]); + var n = Number(arguments[2+2]); + if (populate) { + this.getField(baseName+"theFunction").value=arguments[2+1]; + this.getField(baseName+"numNodes").value=n; + } + if (isGraph) { +% \end{macrocode} +% Is there a function there? We use n to determine +% that, if $n > 0$ we assume a function; otherwise, we +% assume plotted points to be connected. +% \begin{macrocode} + connectPoints = ( n <= 0 ); + if ( connectPoints ) plotPoints = true; + // passing points to be plotted, not connected + } else plotPoints = true; + } +% \end{macrocode} +% Before we calculate the points, let's record what we are graphing. +% \begin{macrocode} + if (afInteractive || populate) + updateGraphData(graph_props,baseName,f); +% \end{macrocode} +% Now we begin calculating the points to plot. +% \begin{macrocode} + var plot_x, plot_y; + var x = (typeof oDR.x_u=="undefined") ? oDR.x_min : oDR.x_l; + var h = rng_x / n; + var thismax = (typeof oDR.x_u=="undefined") ? oDR.x_max : oDR.x_u; +% \end{macrocode} +% The plotted data will be accumulated as XML +% \begin{macrocode} + var cPlotData=<points></points>; +% \end{macrocode} +% We strip out anything of the form \texttt{"y = "}, \texttt{"x = "} or \texttt{"r = "}, +% allowing the user to enter the expressions in equational form \verb!"y = x^2"!, for example. +% \begin{macrocode} + var aSearchResults=/(([a-zA-Z])\s*=\s*)/.exec(f); + if ( aSearchResults != null) { + if ( aSearchResults[2] != "y" && aSearchResults[2] != "r" ) { + syntaxError(); return; + } + } +% \end{macrocode} +% This allows functions of the form $y=f(x)$, $r=f(x)$, $y=f(t)$, $r=f(t)$. +% \begin{macrocode} + f = f.replace(/(([a-zA-Z])\s*=\s*)/g,""); +% \end{macrocode} +% \begin{macrocode} + if ( isGraph && !plotPoints ) { + for (var i=0; i<=n; i++) + { +% \end{macrocode} +% We evaluate the function, and try to detect any errors. If an exception is thrown, +% we display an \textsf{exerquiz} \texttt{syntaxError()} message. If the result is not +% a number, we skip over it. +% \begin{macrocode} + try { with(Math) {_y = eval(f);} } + catch(e) { +% \end{macrocode} +% We have thrown an exception, so either this is bad code, or the user wants us +% to plot this as a polar function. We'll try, but if we're wrong, we'll throw an +% exception in \texttt{Graph\_xyt()}. +% \begin{macrocode} + var paraEqs = "("+f+")*Math.cos(t);("+f+")*Math.sin(t)"; + graph_props.type="polar"; + this.getField(baseName + +"theHiddenFunction").value=paraEqs; + Graph_xyt(graph_props, baseName, pNum); + return; + } + // If not a number then skip over. + if (isFinite(_y)) + { + plot_x = util.printf("\%.10f", x); + plot_y = util.printf("\%.10f", _y); +% \end{macrocode} +% We add the latest data point to the end of the XMList +% \begin{macrocode} + cPlotData.points[cPlotData..point.length()]= + <point><x>{plot_x}</x><y>{plot_y}</y></point> + } + x += h; + } + } else { // prepare to data for plotting +% \end{macrocode} +% At this point the variable f should be a string of +% points to plot.\\ +% \hspace*{30pt}\texttt{f = "(0,1);(2,2);(4,2);...;(5,3)"}.\\ +% It's not clear whether the abcissas need to be sorted in +% increasing order, or whether FLEX is smart enough to do +% that. We'll assume the latter case. +% \begin{macrocode} + var afBegin = (f.indexOf("\(")+1); + var afEnd = f.lastIndexOf("\)"); + cPlotData=f.substring(afBegin,afEnd); + var re = /\)\s*;\s*\(/; + aPlotData= cPlotData.split(re); + var cPlotData=<points></points>; + with (Math) { + for ( var i=0; i<aPlotData.length; i++) { + var cTmp = "["+aPlotData[i]+"]"; + var aTmp = eval(cTmp); +% \end{macrocode} +% We add the latest data point to the end of the XMList +% \begin{macrocode} + cPlotData.points[cPlotData..point.length()]= + <point><x>{aTmp[0]}</x><y>{aTmp[1]}</y></point> + } + } + } + cPlotData=cPlotData.toXMLString(); + var annot = this.getAnnotRichMedia(pNum,"afRM"+baseName); + if ( annot ) + { + if (!annot.activated || wait ) { + annot.activated=true; + afWait4Activation( + graph_props,baseName,pNum,oDR,cPlotData,50); + } + else + annot.callAS("getPlotData", graph_props, oDR, cPlotData); + } +} +% \end{macrocode} +% \DescribeMacro{Graph\_xyt} This function graphs a set of parametric equations in the +% rectangular coordinate system. The function pair is delimited by a semi-colon, early +% in the code we get the function and test whether the function has a semi-colon in its +% definition, so not, we send assume it is a function of a single variable, and send it +% off to \texttt{Graph\_xy}. +% +% For silent mode, the parameters are the same, except that there are two extra arguments, +% the endpoints of the parameter, $t$. The last argument is a Boolean, the author wants the +% graphing data to populate the corresponding fields so user can manipulate. +% \begin{macrocode} +function Graph_xyt(graph_props, baseName, pNum) +{ + _mathVars="t"; + var which_graph=graph_props.graph; + var populate = false; + var afInteractive = (arguments.length <= 3); + if (afInteractive) { + var f = this.getField(baseName+"theHiddenFunction").value; + if ( ck4PtsRe.test(f) || (f.indexOf(";")==-1) ) { + Graph_xy(graph_props, baseName, pNum); + return; + } + f = this.getField(baseName+"theHiddenFunction").value; + } + createGraphData(baseName); + if ( graph_props.type!="polar") graph_props.type="para"; + var aWhichGraph=/(c|p|a)(\d)/.exec(which_graph); + if ( aWhichGraph==null ) aWhichGraph=["","c","1"]; + var isGraph = (aWhichGraph[1]=="c" || aWhichGraph[1]=="a"); + var connectPoints=false; + var plotPoints=false; + var wait=false; + switch(aWhichGraph[1]) { + case "p": + var which_series="p"+aWhichGraph[2]; + plotPoints=true; + break; + case "a": + var which_series="a"+aWhichGraph[2]; + break; + default: + var which_series="c"+aWhichGraph[2]; + } + graph_props.graph=which_series; +% \end{macrocode} +% Get domain and range of x and y, respectively +% obtain in math environment so we can evaluate +% any symbolic constants, such as \texttt{Math.PI} +% \begin{macrocode} + if (afInteractive) { + var oDR = getDomRng (baseName); + var oDp = getParaDom (baseName); + } + else { + wait=graph_props.wait; + populate = graph_props.populate; + var oDR = arguments[5]; + if (populate) populateDomRng(baseName,oDR); + for ( var o in oDR ) oDR[o] = EvalParse(oDR[o]); + var oDp = arguments[6]; + if (populate) populateParaDom(baseName,oDp); + for ( var o in oDp ) oDp[o] = EvalParse(oDp[o]); + } + aGraphData[baseName].aDomRngs = oDR; + aGraphData[baseName].aDom_P = oDp; +% \end{macrocode} +% calculate width of intervals +% \begin{macrocode} + var rng_t = oDp.t_max - oDp.t_min; + /* Get the function and calculated the plotted points */ + if (afInteractive) { + var n = Number(this.getField(baseName+"numNodes").value); + if ( isNaN(n) || n <=0 ) n = \af@defaultNumPoints; + } else { +% \end{macrocode} +% If this is polar, then we need to check if it has been parsed yet. +% \begin{macrocode} + var f = arguments[2+1]; + if ( graph_props.type=="polar") { + if(f.indexOf(";")==-1) { + f = "("+f+")*cos(t);("+f+")*sin(t)"; + f = ParseInput(f); + } + } else + f = ParseInput(f); + var n = Number(arguments[2+2]); + if (populate) { + this.getField(baseName+"theHiddenFunction").value=f; + this.getField(baseName+"theFunction").value=arguments[2+1]; + this.getField(baseName+"numNodes").value=n; + } + if (isGraph) { +% \end{macrocode} +% Is there a function there? We use n to determine +% that, if $n > 0$ we assume a function; otherwise, we +% assume plotted points to be connected. +% \begin{macrocode} + connectPoints = ( n <= 0 ); + if ( connectPoints ) plotPoints = true; + // passing points to be plotted, not connected + } else plotPoints = true; + } +% \end{macrocode} +% Before we calculate the points, let's record what we are graphing. +% \begin{macrocode} + if (afInteractive || populate) + updateGraphData(graph_props,baseName,f); +% \end{macrocode} +% We strip out anything of the form \texttt{"y = "}, \texttt{"x = "} or \texttt{"r = "}, +% allowing the user to enter the expressions in equational form \texttt{"r = 1+sin(t)"}, +% or \texttt{x=sin(t); y = cos(t)}, for example. +% \begin{macrocode} + var aFunction = f.split(";"); + var x_function = aFunction[0]; + var y_function = aFunction[1]; + var aSearchResults=/(([a-zA-Z])\s*=\s*)/.exec(x_function); + if ( aSearchResults != null && aSearchResults[2] != "x") { + syntaxError(); return; + } + x_function = x_function.replace(/(([a-zA-Z])\s*=\s*)/g,""); + aSearchResults=/(([a-zA-Z])\s*=\s*)/.exec(y_function); + if ( aSearchResults != null && aSearchResults[2] != "y") { + syntaxError(); return; + } + y_function = y_function.replace(/(([a-zA-Z])\s*=\s*)/,""); + var plot_x, plot_y; + var t = oDp.t_min; + var h = rng_t / n; + var thismax = oDp.t_max; +% \end{macrocode} +% The plotted data will be accumulated as XML +% \begin{macrocode} + var cPlotData=<points></points>; +% \end{macrocode} +% \begin{macrocode} + if ( isGraph && !plotPoints ) { + for (var i=0; i<=n; i++) + { +% \end{macrocode} +% We evaluate the function, and try to detect any errors. If an exception is thrown, +% we display an \textsf{exerquiz} \texttt{syntaxError()} message. If the result is not +% a number, we skip over it. +% \begin{macrocode} + try { + with(Math) { + _x = eval(x_function); + _y = eval(y_function); + } + } catch(e) { syntaxError(); return;} + // If not a number then skip over. + if (isFinite(_x)&&isFinite(_y)) + { + plot_x = util.printf("\%.10f", _x); + plot_y = util.printf("\%.10f", _y); +% \end{macrocode} +% We add the latest data point to the end of the XMList +% \begin{macrocode} + cPlotData.points[cPlotData..point.length()]= + <point><x>{plot_x}</x><y>{plot_y}</y></point> + } + t += h; + } + } else { // prepare to data for plotting +% \end{macrocode} +% At this point the variable f should be a string of +% points to plot.\\ +% \hspace*{30pt}\texttt{f = "(0,1);(2,2);(4,2);...;(5,3)"}.\\ +% It's not clear whether the abcissas need to be sorted in +% increasing order, or whether FLEX is smart enough to do +% that. We'll assume the latter case. +% \begin{macrocode} + var afBegin = (f.indexOf("\(")+1); + var afEnd = f.lastIndexOf("\)"); + cPlotData=f.substring(afBegin,afEnd); + var re = /\)\s*;\s*\(/; + aPlotData= cPlotData.split(re); + var cPlotData=<points></points>; + with (Math) { + for ( var i=0; i<aPlotData.length; i++) { + var cTmp = "["+aPlotData[i]+"]"; + var aTmp = eval(cTmp); +% \end{macrocode} +% We add the latest data point to the end of the XMList +% \begin{macrocode} + cPlotData.points[cPlotData..point.length()]= + <point><x>{aTmp[0]}</x><y>{aTmp[1]}</y></point> + } + } + } + cPlotData=cPlotData.toXMLString(); + var annot = this.getAnnotRichMedia(pNum,"afRM"+baseName); + if ( annot ) + { + if (!annot.activated || wait ) { + annot.activated=true; + afWait4Activation( + graph_props,baseName,pNum,oDR,cPlotData,50); + } + else + annot.callAS("getPlotData", graph_props, oDR, cPlotData); + } +} +function createGraphData(baseName) +{ + if( aGraphData[baseName] == undefined ) { + aGraphData[baseName] = new Object(); + aGraphData[baseName].aDomRngs=new Object(); + aGraphData[baseName].aDom_P=new Object(); + aGraphData[baseName].current = new Array(); + } +} +% \end{macrocode} +% This function is called by the \texttt{Graph\_xy} or \texttt{Graph\_xyt} +% and updates the graphing data we are trying to track. +% +% Properties of the object +% \verb!aGraphData[baseName].current[which_graph]! object are +% \texttt{hiddenFN} (a string of the hidden JS version of the +% function), \texttt{appearFN} (a string of the function the user +% sees), and \texttt{graph\_props} (the graph properties passed from +% \texttt{Graph\_xy} or \texttt{Graph\_xyt}. +% \begin{macrocode} +function updateGraphData(graph_props,baseName,f) +{ + var which_graph=graph_props.graph; + if (aGraphData[baseName].current[which_graph] == undefined) + aGraphData[baseName].current[which_graph]=new Object(); + aGraphData[baseName].current[which_graph].appearFN + =this.getField(baseName+"theFunction").value; + aGraphData[baseName].current[which_graph].hiddenFN=f; + aGraphData[baseName].current[which_graph].graph_props=graph_props; +} +\end{newsegment} +% \end{macrocode} +% When there are more than three arguments, we are in non-interactive mode. +% The 4th-7th arguments are the domain and range that the graph should be +% set to on reset. +% +% In the flash widget, we call the function \texttt{clearPlotData}, the parameters +% of which are +%\begin{verbatim} +% clearPlotData(graph_props:Object, oDR:Object) +%\end{verbatim} +% \begin{macrocode} +\begin{newsegment}{AF: Supporting Form Fields} +function clearGraph(graph_opts,baseName, pNum) +{ + which_graph=graph_opts.graph; + var aWhichGraph=/(c|p|a)(\d)/.exec(which_graph); + if ( aWhichGraph==null ) aWhichGraph=["","c","1"]; + var isGraph = (aWhichGraph[1]=="c" || aWhichGraph[1]=="a"); + switch(aWhichGraph[1]) { + case "p": + var which_series="p"+aWhichGraph[2]; + break; + case "a": + var which_series="a"+aWhichGraph[2]; + break; + default: + var which_series="c"+aWhichGraph[2]; + } + ProcessIt = false; + afResetForms = new Array (); + for (var i=0; i<afSuffixes.length; i++) + afResetForms.push(baseName+afSuffixes[i]); + this.resetForm(afResetForms); + ProcessIt = true; +% \end{macrocode} +% Now reset the array of graphs plotted. +% \begin{macrocode} + if ( aGraphData[baseName] == undefined ) return; + try { aGraphData[baseName].current = new Array(); } catch(e) {} + var oDR = getDomRng (baseName); + var annot = this.getAnnotRichMedia(pNum,"afRM"+baseName); + if ( annot ) + { + annot.callAS("clearPlotData", {graph:"all"}, oDR); + } + if (event.shift) annot.activated=false; +} +function stripBrackets(aStr) { + var afBegin = (aStr.indexOf("[")+1); + var afEnd = aStr.lastIndexOf("]"); + aStr= aStr.substring(afBegin,afEnd); + return aStr; +} +function EvalParse(str) { + return eval(ParseInput(String(str))); +} +function getDomRng (baseName) +{ + var x_min, x_max, y_min, y_max; + if ( baseName == null ) + return { x_min: \af@DefaultDomMin, y_min: \af@DefaultRngMin, + x_max: \af@DefaultDomMax, y_max: \af@DefaultRngMax }; + var f = this.getField(baseName+"theHiddenDom.min"); + if ( f == null ) { + f = aGraphData[baseName].aDomRngs; + if ( f == null ) + aGraphData[baseName].aDomRngs = { + x_min: \af@DefaultDomMin, y_min: \af@DefaultRngMin, + x_max: \af@DefaultDomMax, y_max: \af@DefaultRngMax }; + } else { + x_min=eval(this.getField(baseName+"theHiddenDom.min").value); + x_max=eval(this.getField(baseName+"theHiddenDom.max").value); + y_min=eval(this.getField(baseName+"theHiddenRng.min").value); + y_max=eval(this.getField(baseName+"theHiddenRng.max").value); + aGraphData[baseName].aDomRngs={ + x_min: x_min, y_min: y_min, + x_max: x_max,y_max: y_max }; + } + return aGraphData[baseName].aDomRngs; +} +function populateDomRng(baseName,oDR) +{ + try{this.getField(baseName+"theDom.min").value=oDR.x_min}catch(e){}; + try{this.getField(baseName+"theDom.max").value=oDR.x_max}catch(e){}; + try{this.getField(baseName+"theRng.min").value=oDR.y_min}catch(e){}; + try{this.getField(baseName+"theRng.max").value=oDR.y_max}catch(e){}; +} +function getParaDom (baseName) +{ + var t_min, t_max; + if ( baseName == null ) + return { t_min: \af@DefaultDomMint, t_max: \af@DefaultDomMaxt }; + var f = this.getField(baseName+"theHiddenDom_t.min"); + if ( f == null ) { + f = aGraphData[baseName].aDom_P; + if ( f == null ) + aGraphData[baseName].aDom_P = { + t_min: \af@DefaultDomMint, + t_max: \af@DefaultDomMaxt }; + } else { + t_min=eval(this.getField(baseName+"theHiddenDom_t.min").value); + t_max=eval(this.getField(baseName+"theHiddenDom_t.max").value); + aGraphData[baseName].aDom_P={ t_min: t_min, t_max: t_max }; + } + return aGraphData[baseName].aDom_P; +} +function populateParaDom(baseName,oDp) +{ + try{this.getField(baseName+"theDom_t.min").value=oDp.t_min} + catch(e){}; + try{this.getField(baseName+"theDom_t.max").value=oDp.t_max} + catch(e){}; +} +function afWait4Activation (graph_props, baseName, pNum,% +oDR, cPlotData, delay) { + var annotName = "afRM"+baseName; + scratchCounter += 1; + aTimeOutArray[scratchCounter] = app.setTimeOut(% +'this.getAnnotRichMedia('+pNum+',"' + +annotName+'").callAS("getPlotData",' + + 'aTimeOutArray['+scratchCounter+'].graph_props,' + + 'aTimeOutArray['+scratchCounter+'].oDR,' + + 'aTimeOutArray['+scratchCounter+'].cPlotData)',50); + aTimeOutArray[scratchCounter].graph_props=graph_props; + aTimeOutArray[scratchCounter].oDR=oDR; + aTimeOutArray[scratchCounter].cPlotData=cPlotData; +} +function shiftHorVert (baseName,pNum,horVert,posNeg) { + var amtShift=baseName+"amtshift"; + if ( horVert=="h" ) { + var LEP = baseName+"theDom.min"; + var UEP= baseName+"theDom.max"; + } else { + var amtShift=baseName+"amtshift"; + var LEP = baseName+"theRng.min"; + var UEP= baseName+"theRng.max"; + } + var amtSft=this.getField(amtShift).value + amtSft=EvalParse(amtSft); + var gf_l=this.getField(LEP); + var gfv_l=Number(EvalParse(gf_l.value)); + gf_l.value = (posNeg=="+") ? + (gfv_l+(Math.abs(amtSft))) : (gfv_l-(Math.abs(amtSft))); + gf_u=this.getField(UEP); + gfv_u=Number(EvalParse(gf_u.value)); + gf_u.value = (posNeg=="+") ? + (gfv_u+(Math.abs(amtSft))) : (gfv_u-(Math.abs(amtSft))); + var g = aGraphData[baseName].aDomRngs; + var oPts = this.getField(baseName+"numNodes"); + var nPts = ( oPts == null ) ? \af@defaultNumPoints : oPts.value; + if ( horVert=="h" ) { + g.x_min=gf_l.value;g.x_max=gf_u.value; + } else { + g.y_min=gf_l.value;g.y_max=gf_u.value; + } + var p = aGraphData[baseName].aDom_P; + for ( var o in aGraphData[baseName].current ) + { + var gd = aGraphData[baseName].current[o]; + gd.graph_props.populate=true; + if ( gd.graph_props.type=="cart" ) { + Graph_xy(gd.graph_props,baseName,pNum, + gd.appearFN,nPts,g); + } else { // gd.graph_props.type=="para" + Graph_xyt(gd.graph_props,baseName,pNum, + gd.appearFN,nPts,g,p); + } + } +} +function zoomInOut (baseName,pNum,posNeg) { + var amtShift=baseName+"amtshift"; + var g = aGraphData[baseName].aDomRngs; + var oPts = this.getField(baseName+"numNodes"); + var nPts = ( oPts == null ) ? \af@defaultNumPoints : oPts.value; +// Begin horizontal calculations + var LEP = baseName+"theDom.min"; + var UEP= baseName+"theDom.max"; + var amtSft=this.getField(amtShift).value + amtSft=EvalParse(amtSft); + var gf_l=this.getField(LEP); + var gfv_l=Number(EvalParse(gf_l.value)); + gf_l.value = (posNeg=="+") ? + (gfv_l+(Math.abs(amtSft))) : (gfv_l-(Math.abs(amtSft))); + gf_u=this.getField(UEP); + gfv_u=Number(EvalParse(gf_u.value)); + gf_u.value = (posNeg=="+") ? + (gfv_u-(Math.abs(amtSft))) : (gfv_u+(Math.abs(amtSft))); +% \end{macrocode} +% Update the \texttt{aGraphData[baseName].aDomRngs} object for horizontal parameters +% \begin{macrocode} + g.x_min=gf_l.value; + g.x_max=gf_u.value; +// Begin vertical calculations + var LEP = baseName+"theRng.min"; + var UEP= baseName+"theRng.max"; + var gf_l=this.getField(LEP); + var gfv_l=Number(EvalParse(gf_l.value)); + gf_l.value = (posNeg=="+") ? + (gfv_l+(Math.abs(amtSft))) : (gfv_l-(Math.abs(amtSft))); + gf_u=this.getField(UEP); + gfv_u=Number(EvalParse(gf_u.value)); + gf_u.value = (posNeg=="+") ? + (gfv_u-(Math.abs(amtSft))) : (gfv_u+(Math.abs(amtSft))); +% \end{macrocode} +% Update the \texttt{aGraphData[baseName].aDomRngs} object for vertical parameters +% \begin{macrocode} + g.y_min=gf_l.value; + g.y_max=gf_u.value; + var p = aGraphData[baseName].aDom_P; + for ( var o in aGraphData[baseName].current ) + { + var gd = aGraphData[baseName].current[o]; + if ( gd.graph_props.type=="cart" ) { + Graph_xy(gd.graph_props,baseName,pNum, + gd.appearFN,nPts,g); + } else { // gd.graph_props.type=="para" + Graph_xyt(gd.graph_props,baseName,pNum, + gd.appearFN,nPts,g,p); + } + } +} +function saveDelSelAction (baseName) +{ + var f = this.getField(baseName+"theFunction"); + var s = this.getField(baseName+"ComboSelect"); + if ( f != null && s != null ) { + var nIndx = s.currentValueIndices; + var cExportV=s.getItemAt(s.currentValueIndices,true); + var cAppearV=s.getItemAt(s.currentValueIndices,false); + if (event.shift) { + s.deleteItemAt(s.currentValueIndices); + s.insertItemAt(cAppearV,("<"+cAppearV+"\afunused>"),nIndx); + s.currentValueIndices=nIndx; + f.value="<"+cAppearV+"\afunused>"; + } else { + var newFunc = f.value; + var newFunc_tmp = newFunc.replace(/\s/g,""); + if ( newFunc_tmp == "" ) { + app.alert({cTitle:"AcroFLeX Graphing", + cMsg:saveDelSelAlerti}); + } else { // something there, let's test it + if(/\afploti/.test(cAppearV) ) { + if (ck4PtsRe.test(newFunc)) { + // A set of points to plot + s.deleteItemAt(s.currentValueIndices); + s.insertItemAt(cAppearV,newFunc,nIndx); + s.currentValueIndices=nIndx; + } else {/* does not appear to be a point */ + app.alert({cTitle:"AcroFLeX Graphing", + cMsg:saveDelSelAlertii}); + } + } else {/* not plot, must be curve*/ + s.deleteItemAt(s.currentValueIndices); + s.insertItemAt(cAppearV,newFunc,nIndx); + s.currentValueIndices=nIndx; + } + } + } + } +} +function graphBtnAction (baseName,pNum) +{ + var s = this.getField(baseName+"ComboSelect"); + var d; + var d, plot_curve="c1"; + if ( s != null ) { + var nIndx = s.currentValueIndices; + var cAppearV=s.getItemAt(s.currentValueIndices,false); + if ( ( d = /\afploti\s+(\d)/.exec(cAppearV) ) != null ) { + plot_curve="p"+d[1]; + } else { + if ( ( d = /\afcurvei\s+(\d)/.exec(cAppearV) ) != null ) { + plot_curve="c"+d[1]; + } else { + app.alert({cTitle:"AcroFLeX Graphing", + cMsg:graphBtnAlerti}); + } + } + } + Graph_xy({graph:plot_curve},baseName,pNum); +} +function afsplitInterval(cInterval) +{ + var aDomTmp=stripBrackets(cInterval); + aDomTmp=aDomTmp.split(","); + return { LEP: aDomTmp[0], UEP: aDomTmp[1] }; +} +\end{newsegment} +\begin{newsegment}{AF: Keystroke/Formatting Functions} +function keystrokeDomRng (fname) +{ + if (event.willCommit) { + var retn = ParseInput(event.value); + if ( !retn ) event.rc = false; + else { + try { eval ( retn ) } + catch(e) { + app.alert({cTitle:"AcroFLeX Graphing", + cMsg:badNumberMsg}); + event.rc=false; + }; + } + } +} +function formatFileInput (fname) +{ + this.getField(fname).value = ParseInput(event.value); +} +function formatVarIntervals (fname) +{ + var val = Number(EvalParse(event.value)); + this.getField(fname).value = val; +} +function formatFunctionInput (fname) +{ + var val = ParseInput(event.value); + this.getField(fname).value = val; +} +function keystrokeFunctionInput () +{ + if (event.willCommit) { + var str = event.value.replace(/\s/g,""); + if ( str == "" ) { + app.alert({cTitle:"AcroFleX Graphing", + cMsg:saveDelSelAlerti}); + event.rc = false; + } + } +} +function keystrokeNumPoints () +{ + try{ + var val = Number(EvalParse(event.value)); + } catch(e) { + app.alert({cTitle:"AcroFLeX Graphing", + cMsg:badNumberMsg}); + event.rc=false; + return; + } + if ( val < 0 ) { + app.alert({cTitle:"AcroFLeX Graphing", + cMsg:negNumberMsg}); + } else { + if ( val == 0 ) { + app.alert({cTitle:"AcroFLeX Graphing", + cMsg:zeroNumberMsg}); + val = \af@defaultNumPoints; + } + } + event.value = Math.ceil(Math.abs(val)); +} +function keystrokeAmtShift() +{ + try{ + var val = Number(EvalParse(event.value)); + } catch(e) { + app.alert({cTitle:"AcroFLeX Graphing", + cMsg:badNumberMsg}); + event.rc=false; + return; + } + if ( val < 0 ) { + app.alert({cTitle:"AcroFLeX Graphing", + cMsg:negShiftMsg}); + } else { + if ( val == 0 ) { + app.alert({cTitle:"AcroFLeX Graphing", + cMsg:zeroShiftMsg}); + val = 1; + } + } + event.value = Math.abs(val); +} +\end{newsegment} +\begin{newsegment}{AF: Support for Custom Graphing Problems} +% \end{macrocode} +% A general purpose function for graphing that takes into consideration all the +% parameters. This is used by the \cs{sgraphLink} and for any JS code that uses +% custom methods. The command \cs{defineGraphJS} is used to set up the parameters +% for this function.. +% \begin{macrocode} +function Graph_xytJS (func,xI,yI,xP,tI,graph,populate,wait,% +type,form,gName,nPts) { + var oDom = afsplitInterval(xI); + var oRng = afsplitInterval(yI); + var oPlotD = afsplitInterval(xP); + var oP=new Object(), oD=new Object(), oDt=new Object(); + oP.graph=graph; + oP.populate=populate; + oP.wait=wait; + if (type!="") oP.type=type; + if (form!="") oP.form=form; + oD={x_min:oDom.LEP,x_max:oDom.UEP,y_min:oRng.LEP,y_max:oRng.UEP,x_l:oPlotD.LEP,x_u:oPlotD.UEP}; + if ( tI=="") { + Graph_xy(oP,gName,this.pageNum,func,nPts,oD); + } else { + var oDom_t = afsplitInterval(tI); + oDt={t_min:oDom_t.LEP,t_max:oDom_t.UEP}; + Graph_xyt(oP,gName,this.pageNum,func,nPts,oD,oDt); + } +} +\end{newsegment} +\end{insDLJS*} +% \end{macrocode} +% Lastly, we define a \texttt{willClose} code and an \texttt{execJS} +% code. The first comes in on the ``developer's hook'' so the user +% can still use the \texttt{willClose} environment without disturbing +% this code. When the document starts to close, we deactivate all +% rich media annotations, to prevent exceptions from being thrown. +% \begin{macrocode} +\begin{defineJS}{\af@WillClose} +for (var n=0; n<this.numPages; n++) { + var rm = this.getAnnotsRichMedia(n); + if ( rm != undefined) { + for (var i=0; i<rm.length; i++ ) rm[i].activated=false; + } +} +\end{defineJS} +% \end{macrocode} +% We save any other developer \texttt{willClose} code, and define ours, after +% replacing any older developer \texttt{willClose} code. +% \begin{macrocode} +\let\af@save@developer@will@Close\developer@will@Close +\def\developer@will@Close{% + \af@save@developer@will@Close + \af@WillClose +} +% \end{macrocode} +% We reset only the form fields in the document created by \textsf{acroflex} and use +% a format script. What this does is to make Acrobat execute the format code +% of any text field (or combo box). The formatting code I've placed causes +% the default functions and values such as \verb!x^2! to be parse, and place +% in the hidden field. This code is used only once when the document is +% first opened by Acrobat then thrown away. The document author needs to +% save the document after opening. +% \begin{macrocode} +\begin{execJS}{afreset} +% try {this.resetForm()} catch(e){}; +var aResetFields=new Array(); +var fname; +var re=/theFunction|theDom|theRng/; +for (var i=0; i< this.numFields; i++) { + fname = this.getNthFieldName(i); + if ( re.test(fname) ) aResetFields.push(fname); +} +if (aResetFields.length !=0) + try {this.resetForm(aResetFields)} catch(e){}; +\end{execJS} +% \end{macrocode} +% We input a customization file for the document author to enter language localizations +% for the tooltip, for example. This file can be placed in the folder of the source file +% of elsewhere on the {\LaTeX} search path. +% \begin{macrocode} +\InputIfFileExists{\af@lang@type}{}{% + \PackageWarning{acroflex}{Could not find the language file + \af@lang@type,\MessageBreak please place this file on the latex + search path.} +} +% \end{macrocode} +%\changes{v1.6}{2015/10/13}{Restore catcodes of subscript and superscript} +% Restore catcodes of subscript and superscript to other. +% \begin{macrocode} +\af@restoreCats +%</package> +% \end{macrocode} +% \section{History} +% This initial roll-out of {\AcroFLeX} occurred on 07/06/08 with version v0.4e. +% Changes since then are listed below. +%\begin{itemize} +% \item (2008/09/26 v0.5b) System freezes when the \cs{domMinP} and \cs{domMaxP} macros are not present, and the +% user enters a function of $t$. Put in some tests to prevent this from happening. +% \item (2008/09/23 v0.5a) Fixed a problem that JS goes into an infinite loop when a non-functional +% expression is in the function input field. +% \item (2008/07/26 v0.5) Worked on compatibility issues with the \texttt{unicode} option of \textsf{hyperref}. +% Defined two commands \cs{eq@nuDV} and \cs{eq@nuV} (in \textsf{eforms}) which prevents hyperref from converting the text to +% octal notation. These are used in the fields that take functions as their initial values, now \verb!x^2! +% does not raise a problem with hyperref even when in unicode mode. Also, made some changes to eforms.dtx +% concerning \cs{r} and \cs{t}. When in unicode mode, these two have to be redefined to \cs{textCR} and +% \cs{textHT}, respectively. +% \item (2008/07/24 v0.4g) Fixed a problem with entering points through the user interface. Now fixed. +% \item (2008/07/18 v0.4f) Identified a problem with parametric equations (interactive mode), +% when one of the expressions involves a power. The system went into an infinite loop, jumping +% between \texttt{Graph\_xy} and \texttt{Graph\_xyt}. Changed the early test to \texttt{theFunction} +% rather than \texttt{theHiddenFunction}. +% \item[] Added the new series \texttt{a1}, \texttt{a2}, \texttt{a3}, and \texttt{a4} as values of the graph key of \cs{sgraphLink}. These are similar to the c counterparts, but +% shade in the graph between the x-axis and the graph. For parametric equations, the results seem +% good, but could be unpredictable. +%\end{itemize} +% \Finale +\endinput diff --git a/texmf-dist/source/latex/acroflex/acroflex.ins b/texmf-dist/source/latex/acroflex/acroflex.ins new file mode 100644 index 00000000..0b53dfae --- /dev/null +++ b/texmf-dist/source/latex/acroflex/acroflex.ins @@ -0,0 +1,60 @@ +%% +%% This file will generate fast loadable files and documentation +%% driver files from the doc files in this package when run through +%% LaTeX or TeX. +%% +%% Copyright 1999-2006 D. P. Story +%% +%% This file is part of the `AcroTeX eDucation Bundle'. +%% ------------------------------------------- +%% +%% It may be distributed under the conditions of the LaTeX Project Public +%% License, either version 1.2 of this license or (at your option) any +%% later version. The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.2 or later is part of all distributions of LaTeX +%% version 1999/12/01 or later. +%% +%% --------------- start of docstrip commands ------------------ +%% +\def\filedate{2008/07/01} +\def\batchfile{acroflex.ins} + +\input docstrip +\ifx\generate\undefined + \Msg{**********************************************} + \Msg{*} + \Msg{* This installation requires docstrip} + \Msg{* version 2.4 or later.} + \Msg{*} + \Msg{* An older version of docstrip has been input} + \Msg{*} + \Msg{**********************************************} + \errhelp{Move or rename old docstrip.tex and get a newer one.} + \errmessage{Old docstrip in input path} + \batchmode + \csname @@end\endcsname\end +\fi + +\keepsilent +\askforoverwritefalse +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\preamble +\endpreamble + +\generate +{% + \file{acroflex.sty}{\from{acroflex.dtx}{copyright,package}} +} + +\Msg{***************************************************************} +\Msg{*} +\Msg{* \space To finish the installation you have to copy the files } +\Msg{*} +\Msg{* \space *.sty, *.cfg and *.def into a directory searched by TeX} +\Msg{*} +\Msg{***************************************************************} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\endinput diff --git a/texmf-dist/source/latex/acroflex/doc/acroflex_man.tex b/texmf-dist/source/latex/acroflex/doc/acroflex_man.tex new file mode 100644 index 00000000..63bbcbb8 --- /dev/null +++ b/texmf-dist/source/latex/acroflex/doc/acroflex_man.tex @@ -0,0 +1,1073 @@ +% makeindex < acroflex_man.idx > acroflex_man.ind +\documentclass{article} +\usepackage[fleqn]{amsmath} +\usepackage[ + web={centertitlepage,designv, + nodirectory,forcolorpaper, + latextoc,pro}, + eforms, + linktoattachments, + aebxmp +]{aeb_pro} +\usepackage[dvipsone,showembeds]{graphicxsp} +\usepackage{array} +\usepackage[altbullet]{lucidbry} +%\usepackage{myriadpro} + +%\usepackage{makeidx} +%\makeindex +\usepackage{acroman} +\usepackage[active]{srcltx} + +\makeatletter +\renewcommand{\paragraph} + {\@startsection{paragraph}{4}{0pt}{6pt}{-3pt}{\bfseries}} +\renewcommand*\l@subsection{\@dottedtocline{2}{1.5em}{2.5em}} +\renewcommand*\descriptionlabel[1]{\hspace\labelsep + \normalfont #1} +\newcommand{\aebDescriptionlabel}[1]{% + \setlength\dimen@{\amtIndent+\labelsep}% + {\hspace*{\dimen@}#1}} +\makeatother +\newenvironment{aebDescript} + {\begin{list}{}{\setlength{\labelwidth}{0pt}% + \setlength{\leftmargin}{\leftmargin}% + \setlength{\leftmargin}{\leftmargin+\amtIndent}% + \setlength\itemindent{-\leftmargin}% + \let\makelabel\aebDescriptionlabel + }}{\end{list}} + +\def\AEBBook{\textsl{{Acro\!\TeX} eDucation System Tools: {\LaTeX} for interactive PDF documents}} +\def\AcroBlog{{Acro\!\TeX} Blog} + +\newcommand\refctan[1]{\href{http://ctan.org/pkg/#1}{ctan.org/pkg/#1}} +\newlength{\aebdimen} +\def\anglemeta#1{$\langle\textit{\texttt{#1}}\rangle$} +%\def\meta#1{\textit{\texttt{#1}}} +\let\meta\anglemeta +\let\pkg\textsf +\let\env\texttt +\let\opt\texttt +\let\app\textsf +\def\RMA{RMA} +\let\SC\relax +\def\SWF{SWF} +\def\FLV{FLV} +\let\EXT\relax +\def\AcroFLeX{AcroF\kern-.1667em + \lower.5ex\hbox{L}\kern-.3eme\kern-.125emX\@} +\def\AEB{\textsf{AeB}} +\def\AcroTeX{Acro\!\TeX} +\def\HTML{HTML}\def\FDF{FDF} +\def\PDF{PDF}\def\URL{URL} +\let\amtIndent\leftmargini +\def\bNH{\begin{NoHyper}}\def\eNH{\end{NoHyper}} +\def\nhnameref#1{\bNH\nameref{#1}\eNH} +\def\nhNameref#1{\bNH\Nameref{#1}\eNH} +\def\nhurl#1{\bNH\url{#1}\eNH} +\def\grayV#1{\textcolor{gray}{#1}} +\def\darg#1{\{#1\}} +\def\parboxValign{t} +\renewcommand*{\backrefalt}[4]{% + \ifcase #1\or + See page~#2.\else See pages~#2.\fi +} +\newenvironment{aebQuote} + {\list{}{\leftmargin\amtIndent}% + \item\relax}{\endlist} +\newcommand{\FmtMP}[2][0pt]{\mbox{}\marginpar{% + \raisebox{.5\baselineskip+#1}{% + \expandafter\parbox\expandafter[\parboxValign]% + {\marginparwidth}{\aebbkFmtMp#2}}}} +\def\aebbkFmtMp{\kern0pt\itshape\small + \color{blue}\raggedright\hspace{0pt}} +\newcommand{\BlogArticle}{\makebox[0pt][l]{\hspace{-1pt}\color{blue}\Pisymbol{webd}{254}% + }\raisebox{.5pt}{\color{red}\ding{045}}} +\def\dps{$\mbox{$\mathfrak D$\kern-.3em\mbox{$\mathfrak P$}% + \kern-.6em \hbox{$\mathcal S$}}$} +\def\FitItIn{\eq@fititin} +\def\endredpoint{\FitItIn{{\large\ifusebw\color{black}\else\color{red}\fi$\blacktriangleleft$}}} + +\def\takeMeasure{\bgroup\obeyspaces\takeMeasurei} +\def\takeMeasurei#1{\global\setbox\webtempboxi\hbox{\ttfamily#1}\egroup} + + +\urlstyle{rm} + +\def\expath{../examples} + +\DeclareDocInfo +{ + university={\AcroTeX.Net}, + title={\texorpdfstring{\AcroFLeX\\[1em] + The {\AcroTeX} and FLEX/Flash Connection\\[1em]Applications to Graphing}{The AcroFLeX + Graphing System}}, + author={D. P. Story}, + email={dpstory@acrotex.net}, + subject={Documentation for AcroFLeX}, + talksite={\url{www.acrotex.net}}, + version={1.6c}, + keywords={SWF, Adobe FLEX, Adobe Acrobat, JavaScript, ActionScript, AcroTeX}, + copyrightStatus=True, + copyrightNotice={Copyright (C) \the\year, D. P. Story}, + copyrightInfoURL={http://www.acrotex.net} +} + +\def\dps{$\hbox{$\mathfrak D$\kern-.3em\hbox{$\mathfrak P$}% + \kern-.6em \hbox{$\mathcal S$}}$} + +\setWindowOptions{showtitle} + +\universityLayout{fontsize=Large} +\titleLayout{fontsize=LARGE} +\authorLayout{fontsize=Large} +\tocLayout{fontsize=Large,color=aeb} +\sectionLayout{indent=-62.5pt,fontsize=large,color=aeb} +\subsectionLayout{indent=-31.25pt,color=aeb} +\subsubsectionLayout{indent=0pt,color=aeb} +\subsubDefaultDing{\texorpdfstring{$\bullet$}{\textrm\textbullet}} + +%\pagestyle{empty} +%\parindent0pt\parskip\medskipamount + +\definePath\bgPath{"C:/Users/Public/Documents/% + ManualBGs/Manual_BG_Print_AeB.pdf"} +\begin{docassembly} +\addWatermarkFromFile({ + bOnTop:false, + cDIPath: \bgPath +}); +\executeSave(); +\end{docassembly} + +\begin{document} + +\maketitle + +\selectColors{linkColor=black} +\tableofcontents +\selectColors{linkColor=webgreen} + +\section{Introduction} + +The \textbf{{\AcroFLeX}} Graphing Bundle is used to create a +\emph{graphing screen} that can be incorporated into a PDF document +and viewed within \app{Adobe Acrobat Reader}, version 9.0 or later. The graphing +screen can be interactive or non-interactive. + +For the interactive graphing screen, the user can enter an +expression representing a function of a single variable $x$, a polar +function of $t$, or a set of parametric equations that are functions +of $t$. Various controls are provided to change the viewing window, +for shifting horizontally and vertically, and for zooming in or out. + +For the non-interactive graphing screen, the screen is populated +when the user clicks a link created by \cs{sgraphLink}. +\cs{sgraphLink} passes such information as the function, +domain, and range to the graphing routines of {\AcroFLeX}. + +In this version of {\AcroFLeX}, up to four functions can be graphed +and four sets of plotted points can be displayed, on one graphing +screen. + +The graph screen itself is actually a SWF file, named +\texttt{acroflex.swf}. This SWF file is part of the {\AcroFLeX} +distribution. This package uses the \pkg{rmannot} package, also +written by this author, to create rich media annotations, to embed +\texttt{acroflex.swf} in the PDF document, and to display the SWF through +the rich media annotation. + +\subsection{Background} + +Version 9 of Acrobat/Adobe Reader introduces the \textit{rich media +annotation} which plays FLV movies, and SWF animations, and MP3 files.\footnote{% +The rich media annotation is introduced in +\textsl{Adobe Supplement to the ISO 32000}, which documents +BaseLevel 1.7, ExtensionLevel 3, the Adobe's extensions to PDF~1.7.} +Acrobat/Adobe Reader also provides a scripting bridge between +JavaScript for Acrobat, and ActionScript, the scripting language of +Flash player. This bridge enables the PDF and the Flash widget, +embedded in the rich media annotation, to communicate. The scripting +bridge opens up wonderful opportunities for applications to the +education sector. The {\AcroFLeX} Graphing Bundle is one such +application of the new PDF-Flash connection to education. + +\textbf{{\AcroFLeX}} uses the commercial product Adobe FLEX +Builder~3 and FLEX~3 SDK to produce Flash widgets, and the AeB to +create PDF documents with appropriate JavaScript to communicate with +the Flash widget. FLEX Builder~3 is currently free for students and +educators, the FLEX 3 SDK is free to all. + +% This style file defines some basic controls for +% \textbf{{\AcroFLeX} Graphing} for controlling graphical SWF files +% for graphing. +% +% These commands are general {\LaTeX} commands, that require no special driver, so +% they can be used by, for example, pdftex; however, we use SWF files to produce +% the graphing screen with the built-in ActionScript to communicate with the PDF. +% For this, you will need Acrobat 9 Pro. In that case, you might as well use the +% Acrobat Distiller to produce your PDF, but it is not necessary. + +\subsection{What is \texorpdfstring{{\AcroFLeX}}{AcroFLeX}?} + +The word \textbf{\AcroFLeX} is meant to convey a merging of two computer technologies: +\begin{itemize} +\item \textbf{Acro}: connotes both \textbf{Adobe Acrobat} (\textbf{Adobe Reader}) +and \textbf{{Acro\negthinspace\TeX}} (as in the +\textbf{{Acro\negthinspace\TeX} eDucation Bundle} or, just \textbf{AeB}). +\item \textbf{F\kern-.1667em\lower.5ex\hbox{L}\kern-.3eme\kern-.125emX\@}: connotes + \textbf{Adobe FLEX 3}. FLEX 3 is used to create SWF files to interact with the user. + In the case of graphing, plotting information is passed from Acrobat, via JavaScript, + to the Flash widget. ActionScript takes the data, and plots the points provided, and + connects them with a smooth curve. +\end{itemize} + + +\section{Requirements} + +In this section we list the requirements for this package. + +\subsection{{\LaTeX} Package Requirements} + +The preamble of the demo file afgraph.tex lists: +\begin{Verbatim}[xleftmargin=\amtIndent,numbers=left] +\usepackage[% + driver=dvips, + web={nodirectory,pro,tight,usesf}, + eforms,exerquiz,dljslib={ImplMulti}, + graphicxsp={showembeds} +]{aeb_pro} +\usepackage{acroflex} +\end{Verbatim} +Let me comment on each of these lines. +\begin{itemize} + \item Line~(7): Of course, we use the \pkg{acroflex} package. The + \pkg{acroflex} package \textit{requires} the \pkg{rmannot} package. + The latter package is the one that creates the rich media annotation, + embeds the graphing Flash widget, acroflex.swf, and displays it. The + \pkg{rmannot} package is the only one listed in \texttt{acroflex.dtx} + as required, however, more packages are really required, as discussed + in the next items. + + \item Lines (1)--(6): The \pkg{aeb\_pro} package is \textit{strongly + recommended}. The {\AcroFLeX} Graphing Bundle uses the + \texttt{willClose} environment to assure the document will behave + properly when the user closes the document. + + The options use the so-called \textbf{AeB Control Central} that represent + a convenient way to input the other required packages (in optimal order) + needed by the \pkg{acroflex} package. + + If \texttt{aeb\_pro} is not used, then the individual + required packages must be input using the \cs{usepackage} + mechanism. + + We input the \texttt{aeb\_pro} package before the + \pkg{acroflex} package. + + We now comment on each of the options used in the \texttt{aeb\_pro} + package: + \begin{description} + \item[Line (2), the \texttt{driver} option:] This system uses \app{Acrobat + Distiller}, which distills a PostScript file. The driver values + this package uses are \texttt{dvips} and \texttt{dvipsone}. + Setting the driver is important because the dvi-to-ps application + (\texttt{dvips} and \texttt{dvipsone}) consumes the dvi file + produced by the {\TeX} compiler and writes a PostScript file that + Acrobat Distiller consumes. + + \item [Line (3), the \texttt{web} option:] The \texttt{web} package + is not really required. It is used to create a PDF page size + convenient to view on a computer monitor. This package has many + options and features for the document author to design a document + for screen---or for paper---viewing. + + The \pkg{web} package brings in the \pkg{hyperref} package, which is + a \textit{required package}. If \texttt{web} is not used, + \pkg{hyperref} needs to be input. + + \item [Line (4), the \texttt{eforms} option:] A \textit{required} + package. This package provides form field and link support for + the {\AcroFLeX} Graphing Bundle. The \texttt{eforms}, in turn, + inputs the \texttt{insdljs} package, which provides support for + document-level JavaScript. It is the document-level JavaScript + where much of the work is done: parsing input, calculating + graphing data, and sending this data off to the + \texttt{acroflex.swf} widget for display. + + \item [Line (4), the \texttt{exerquiz} option:] A \textit{required} + package. The \texttt{exerquiz} package has several function + parsing methods defined in its document-level JavaScript. + {\AcroFLeX} uses these parsing routines. One of these days, I'll + separate out the parsing routines from \texttt{exerquiz}, but not + now. + + \item [Line (4), the \texttt{dljslib} option:] An optional, \emph{but + recommended} package. We use this package for its + \texttt{ImplMulti} option. This option simplifies the problem of + entering functional expressions. Without the \texttt{ImplMulti}, + to enter $2x\sin^2(2x)$, the user must type explicit + multiplications, \verb!2*x*(sin(2*x))^2!, with the + \texttt{ImplMulti} option, the user needs only enter + \verb!2xsin^2(2x)!. + + \item [Line (5), the \texttt{graphicxsp} option:] The \texttt{graphicxsp} is a + \textit{required} package of \pkg{rmannot}, but we input it + earlier so we can set its options through the \textbf{AeB Control + Central} (part of AeB Pro). The \texttt{graphicxsp} package, part + of the AeB Pro Bundle, provides embedding of poster graphics for + a rich media annotation. A poster graphic is the appearance you + see when the annotation is not activated. + + \end{description} +\end{itemize} + +\subsection{PDF Creator Requirements} + +This package requires Acrobat Distiller 9.0 (or later) to convert +PostScript files to PDF. Because this package uses \pkg{rmannot} +to create rich media annotations, there is also a requirement that +the Distiller must be opened using the \texttt{-F} command line +flag. See the documentation of the \pkg{rmannot} package for more +details. + +\subsection{Installation} + +The installation of the \pkg{acroflex} package is +straightforward. Place \texttt{acroflex.zip} in the search path of +your {\TeX} system and unzip. Unzipping creates a folder named +\pkg{acroflex}. Refresh your filename database, if your system +requires it. + +Accompanying the distribution is a file named \texttt{acroflex.cfg}. +Open this file in your favorite text editor and you see the +following lines. +\begin{Verbatim} + % + % AcroFleX Graphing Bundle Configuration File + % D. P. Story, dpstory@acrotex.net + % + \pathToAcroFlex{C:/acrotex/aebpro/acroflex/swf} +\end{Verbatim} +Edit the argument of \cs{pathToAcroFlex} (defined in the +\pkg{acroflex} package) to the path of the folder that contains +the \texttt{acroflex.swf} Flash file. Save and close +\texttt{acroflex.cfg}. + +Of course, you need to install the latest versions of AeB (the +{\AcroTeX} eDucation Bundle), AeB Pro, \texttt{graphicxsp}, and +\pkg{rmannot}. Follow the package documentation closely for +installation, some of the packages require that certain JavaScript +file be installed. + + +\section{The \texorpdfstring{\AcroFLeX}{AcroFLeX} Graphing System} + +This package defines several document scripts, the two primary ones are +\texttt{Graph\_xy()} and \texttt{Graph\_xyt()}, the others support these two. +\texttt{Graph\_xy()} and \texttt{Graph\_xyt()} take the data passed to it, +parse it, create plot data, and send it off to the {\AcroFLeX} graphing +widget to graph the data by way of the infamous scripting bridge. Details of +these functions can be found in the documentation in the +\texttt{acroflex.dtx} file. + +In the {\AcroFLeX} graphing system there are three modes of +operation: interactive, populate, and silent. +\begin{itemize} +\item \textbf{Interactive:} This occurs when the user enters a +function through the UI. + +The following controls are \emph{required}: +\begin{Verbatim} + \funcInputField, \graphBtn, \numPoints + \domMin, \domMax, \rngMin, \rngMax, +\end{Verbatim} +If parametric or polar graphs are to be used, +then \cs{domMinP} and \cs{domMaxP} are also required. The other +controls are \emph{optional}: +\begin{Verbatim} + \graphClrBtn + \amtShift (\hShiftL, \hShiftR, \vShiftD, \vShiftU) + \zoomInOut, \savedelSelBtn, \functionSelect +\end{Verbatim} +The \cs{graphClrBtn} button is recommended, though not required. +All these commands will be discussed in detail in the pages that follow. + +\item \textbf{Populate:} The populate mode occurs when the graphing + parameters are passed to \texttt{Graph\_xy} (or \texttt{Graph\_xyt}) by + \cs{sgraphLink} (or some other command). All the essential information + is passed as arguments. The target graphing screen has all the required + controls, as listed above. The command initiating the graphing must set + the \texttt{graph\_props.populate} property to \texttt{true}. In this + case the graphing data populate the required fields and the graph will + be drawn. It is the document author's responsibility to only use + populate on graphing screens that have all the required control fields. + + Populate behaves exactly like interactive, but the graphing data is + passed to the graphing routines in pre-packaged form, prepared by the + document author; the user, however, can manipulate the curve once it + appears. + + The required controls are the same as the interactive mode. + +\item \textbf{Silent:} In the silent or \emph{non-interactive} mode, there + must be no controls other than \cs{graphClrBtn}. Basically, the + document author prepares some pre-packaged graphs to be displayed to + the user, without interaction. These may go along with a tutorial + discussion symmetry, periodicity, tangent lines, etc. + + If the document author wants the user to interact with the graph, the + required controls need to be supplied and the + \texttt{graph\_props.populate} property needs to be set to \texttt{true}. + That is, use the populate mode. + +\end{itemize} + +\subsection{Setting up the Graphing Screen} + +It should be a hard and fast rule that all content concerning a +graphing screen should occur on the same page as the rich media +annotation that displays the graphing screen. Should discussion +cross page boundaries, create another graphing screen for that page. +Never fear, the {\AcroFLeX} graphing widget is only embedded once, +so adding more screens does not bloat the size of the file. + +There are three commands to set up an {\AcroFLeX} graph screen: +\Com{dimScreenGraph}, \Com{graphName} and \Com{graphScreen}. The use of +the command \cs{dimScreenGraph} is not required, but recommended. +\takeMeasure{\string\graphScreen[\meta{rma\_options}]\{\meta{width}\}\{\meta{height}\}} +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\dimScreenGraph{!meta(width)}{!meta(height)} +\graphName{!meta(unique_name)} +\graphScreen[!meta(rma_options)]{!meta(width)}{!meta(height)} +\end{dCmd} + +\CmdDescription We describe each of these three, and their parameters. +\begin{itemize} + \item \cs{dimScreenGraph}: This command is a convenient way of setting the dimensions + of the graphing screen. You specify the width of the screen using the \meta{width} + parameter and the height of the screen using the \meta{height} parameter. These values + are passed through a \cs{setlength}, so simple calculations on the dimension can be performed + on the parameters. (The \texttt{calc} package is used by the web package.) This command then + defines macros \Com{hScreenGraph} and \Com{vScreenGraph} to hold these two dimensions, respectively. + \cs{hScreenGraph} and \cs{vScreenGraph} can be used in \cs{graphScreen}, or in setting up + \texttt{minipage}s based on these lengths, for example. + + \item[] If the aspect ratio of all your graphing screens is going to be the same, then + it suffices to use \cs{dimScreenGraph} only once in the document. + + \item \cs{graphName}: Use this command to define a unique name for this graphing screen. Each + screen must have a different name. This command defines the text macro \Com{afgraphName}, which + expands to the given name. + + \item \cs{graphScreen}: This is the main command of this package, + it's the one that creates a rich media annotation and associates + it with the {\AcroFLeX} Graphing widget. It has three parameters: + %\begin{aebQuote} + \begin{description}\def\NH{\hspace{-\labelsep}} + \item \NH\meta{rma\_options} is optional and just passes to the underlying + command \Com{rmAnnot} (defined in the \pkg{rmannot} + package) that actually creates the rich media annotation. + The most ``important'' key-value pair, for this package, + is the \texttt{poster} key, through this key, a poster can + be associated with the annotation. + \item \NH\meta{width} is the width of the graph screen, if \cs{dimScreenGraph} was used, + just use \cs{hScreenGraph} as this value. + \item\NH\meta{height} is height the screen of the graph screen, if \cs{dimScreenGraph} was used, + just use \cs{vScreenGraph} as this value. + \end{description} +% \end{aebQuote} +\end{itemize} +The \cs{graphScreen} can be resized using \cs{resizebox} or +\cs{scalebox} (from the \texttt{graphicx} package) to obtain a +larger or smaller graph screen with the same aspect ratio. + + +The following is an example of the usage of each of these three commands. Note that the +height is three-fourths that of the width. + +\takeMeasure{\string\graphScreen[poster=aflogo]\{\string\hScreenGraph\}\{\string\vScreenGraph\}} +\begin{dCmd*}{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\dimScreenGraph{186bp}{186bp*3/4} +\graphName{graph1} +\graphScreen[poster=aflogo]{\hScreenGraph}{\vScreenGraph} +\end{dCmd*} + +\paragraph*{Graphing Screen in a Floating Window.} The graphing +window can appear in a floating window as well. The +\Com{iconFloatGraphScreen} command is used to create such a screen. + +\takeMeasure{\string\iconFloatGraphScreen[\meta{key\_values}]\{\meta{width}\}\{\meta{height}\}} +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\iconFloatGraphScreen[!meta(key_values)]{!meta(width)}{!meta(height)} +\end{dCmd} +\PD The command has three parameters. The first optional one is passed as the +first optional parameter of the underlying \cs{graphScreen} command. The +\cs{graphScreen} command uses \Com{hScreenGraph} and \Com{vScreenGraph}, +defined through the \cs{dimScreenGraph} command, to set the dimensions of the +graph screen. The graph screen is then resized using \Com{resizebox} from the +\texttt{graphicx} package. The other two parameters, \meta{width} and +\meta{height}, are simply passed to \cs{resizebox}. See the documentation on +\cs{resizebox} for details on these parameters. + +For example,\takeMeasure{\string\iconFloatGraphScreen[poster=aflogo]\{40bp\}\{!\}} +\begin{dCmd*}{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\iconFloatGraphScreen[poster=aflogo]{40bp}{!} +\end{dCmd*} +\noindent The first parameter is used to define a poster of the icon, the +second parameter is \texttt{40bp} which means to resize the graphic +to a width of \texttt{40bp}, the third parameter of exclamation +point (!) signals \cs{resizebox} to maintain the aspect ratio of the +graphic. + +The \cs{iconFloatGraphScreen} command is implemented by creating a +rich media annotation for the {\AcroFLeX} Graphing widget, with a +form field button on top of it that is transparent. Pressing on the +icon is actually pressing on the button. The button action activates +the graphing screen if it is not activated, and deactivates it if it +is activated. The graphing screen might be the target of graphing +data sent to it by the \cs{sgraphLink} command, see +\hyperref[sgraphlink]{Section~\ref*{sgraphlink}}, +page~\pageref*{sgraphlink}, or through the graphing screen controls, +these are explained next. + +\subsection{Graphing Screen Controls} + +The controls described in this section are used for interactive and +populate modes. + +\subsubsection{Required Controls} + +For interactive or populate mode, in addition to \cs{graphScreen}, +several controls are required so the user can manipulate the graph. + +\takeMeasure{\string\funcInputField[\meta{key\_values}]\{\meta{width}\}\{\meta{height}\}} +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\funcInputField[!meta(key_values)]{!meta(width)}{!meta(height)} +\end{dCmd} +\CmdDescription The field created by +\cs{funcInputField}\footnote{The command was originally misnamed +\cs{fileInputField} and is still recognized by the {\AcroFLeX} +package; however, document authors should use the command +\cs{funcInputField}.} is used to enter a function or a set of points +to be graphed. The function is parsed by the \texttt{exerquiz} +routines, so the same syntax that is used for \texttt{exerquiz} +quizzes and short quizzes is used. The \meta{key\_values} are +passed to the underlining text field and can be used to change the +appearance of the field, see the \texttt{eformman.pdf} for more +information. The \meta{width} and \meta{height} are the +width and height, respectively, of the text field. + +\takeMeasure{\string\graphBtn[\meta{key\_values}]\{\meta{width}\}\{\meta{height}\}} +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\graphBtn[!meta(key_values)]{!meta(width)}{!meta(height)} +\end{dCmd} +\CmdDescription The graph button. Once the user has entered a +required data into the required fields, the user press this button +and the graph appears in the graph screen. The parameters are the +same as for \cs{funcInputField}, the descriptions are the same. + +\takeMeasure{\string\numPoints[\meta{key\_values}]\{\meta{width}\}\{\meta{height}\}} +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\numPoints[!meta(key_values)]{!meta(width)}{!meta(height)} +\end{dCmd} +\CmdDescription This text field displays the number of points to be +plotted. It is editable, the user can change this value. The +parameters are the same as for \cs{funcInputField}, the descriptions +are the same. + + +\takeMeasure{\string\domMin[\meta{key\_values}]\{\meta{width}\}\{\meta{height}\}} +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\domMin[!meta(key_values)]{!meta(width)}{!meta(height)} +\domMax[!meta(key_values)]{!meta(width)}{!meta(height)} +\rngMin[!meta(key_values)]{!meta(width)}{!meta(height)} +\rngMax[!meta(key_values)]{!meta(width)}{!meta(height)} +\end{dCmd} +\CmdDescription The graphing window is set by these four text +fields. When the curve is graphed, only the rectangular window, +\begin{quote} +$[\,\cs{domMin}, \cs{domMax}\,] \times [\,\cs{rngMin}, +\cs{rngMax}\,]$ +\end{quote} +is displayed.\footnote {By this notation, I mean the +intervals determined by the values of these intervals.} The +parameters are the same as for \cs{funcInputField}, the descriptions +are the same. + +If parametric and polar graphing is required of the user, +\cs{domMinP} and \cs{domMaxP} are required as well. + +\takeMeasure{\string\domMinP[\meta{key\_values}]\{\meta{width}\}\{\meta{height}\}} +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\domMinP[!meta(key_values)]{!meta(width)}{!meta(height)} +\domMaxP[!meta(key_values)]{!meta(width)}{!meta(height)} +\end{dCmd} +\CmdDescription The interval $[\,\cs{domMinP}, \cs{domMaxP}\,]$ is +the interval over which a set of parametric equations is traced; in +the case of polar functions, this interval is used for the domain of +the polar function. The parameters are the same as for +\cs{funcInputField}, the descriptions are the same. + +\paragraph*{Setting the default values.} Whereas it is possible to +set the default values of the fields just described, a more +convenient method is used. + +\takeMeasure{\string\defaultDomRng% +\{\meta{x\_min}\}\{\meta{x\_max}\}\{\meta{y\_min}\}\{\meta{y\_max}\}} +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\defaultFunction{!meta(!upshape(function|points))} +\defaultNumPoints{!meta(postive_integer)} +\defaultDomRng{!meta(x_min)}{!meta(x_max)}{!meta(y_min)}{!meta(y_max)} +\defaultDomP{!meta(t_min)}{!meta(t_max)} +\end{dCmd} + +\noindent These can be executed, along with \cs{graphName}, just before the +\cs{graphScreen} command. The values of their parameters will then populate +the corresponding fields as default values. + +The following are the default values of all the required fields, as +defined by the \pkg{acroflex} package. Note that all of these are +parsed (with the exception of the number of points) using +\texttt{exerquiz}'s parsing routines; consequently, a value such as +\texttt{2*PI} is perfectly legal. + +\takeMeasure{\string\defaultDomRng\darg{-2}\darg{2}\darg{0}\darg{4}} +\begin{dCmd*}{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\defaultFunction{x^2} +\defaultNumPoints{40} +\defaultDomRng{-2}{2}{0}{4} +\defaultDomP{0}{2*PI} +\end{dCmd*} + +\subsubsection{Optional Controls} + +There are several other optional controls that may be useful in manipulating +a graph. + +\takeMeasure{\string\graphClrBtn[\meta{key\_values}]\{\meta{width}\}\{\meta{height}\}} +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\graphClrBtn[!meta(key_values)]{!meta(width)}{!meta(height)} +\end{dCmd} +On clicking this button, the current graphing screen is cleared of +all graphs and plotted points. Shift-clicking this button +deactivates the graphing screen, and the annotation's poster +appears. + +\paragraph*{Multiple Plots.} By using the \Com{functionSelect} combo +box, the user can graph multiple curves. + +\takeMeasure{\string\functionSelect[\meta{key\_values}]\{\meta{width}\}\{\meta{height}\}} +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\savedelSelBtn[!meta(key_values)]{!meta(width)}{!meta(height)} +\functionSelect[!meta(key_values)]{!meta(width)}{!meta(height)} +\end{dCmd} +The \cs{functionSelect} combo box serves several purposes. It consists of +eight items that appear as \texttt{Curve\,1}, \texttt{Curve\,2}, +\texttt{Curve\,3}, \texttt{Curve\,4}, \texttt{Plot\,1}, \texttt{Plot\,2}, +\texttt{Plot\,3}, \texttt{Plot\,4}. When this combo box is present, the user +is able to graph multiple curves and plots. Changing the combo box to +\texttt{Curve\,2}, for example, and pressing the \cs{graphBtn} button, the +function will be graphed on \texttt{Curve\,2}. There are four curves possible, +and four sets of plotted points. The different curves and plots are color +coded. + +When the \cs{savedelSelBtn} is also present, the user can click on +it and save the function definition under that curve or plot. These +expressions will only be saved during the current viewing session in +\app{Acrobat Reader}, but if the user is on Acrobat, the PDF can be saved +and the values added to the combo list will be saved as well. + +The parameters are the same as for +\cs{funcInputField}, the descriptions are the same. + +\paragraph*{Horizontal and Vertical Shifting.} There are several +controls that shift the graphing window vertically or horizontally. + +\takeMeasure{\string\amtShift[\meta{key\_values}]\{\meta{width}\}\{\meta{height}\}} +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\amtShift[!meta(key_values)]{!meta(width)}{!meta(height)} +\hShiftL{!meta(text)} +\hShiftR{!meta(text)} +\vShiftU{!meta(text)} +\vShiftD{!meta(text)} +\end{dCmd} +The \cs{amtShift} is a text field, its value is a positive number +that will be used to shift the graphing window horizontally or +vertically. The user can change this value. The parameters are the +same as for \cs{funcInputField}, the descriptions are the same. + +The other four commands are implemented as links, then clicked, the +graphing window moves the amount specified in \cs{amtShift} field +left (\cs{hShiftL}), right (\cs{hShiftR}), up (\cs{vShiftU}) or down +(\cs{vShiftD}). The argument \meta{text} is the text to be used +to identify the link. + +\paragraph*{Zoom, zoom, zoom.} + +The user can be allowed to optionally zoom the graph out or in by providing the +control \Com{zoomInOut}. + +\takeMeasure{\string\zoomInOut[\meta{key\_values}]\{\meta{width}\}\{\meta{height}\}} +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\zoomInOut[!meta(key_values)]{!meta(width)}{!meta(height)} +\end{dCmd} +Click the \cs{zoomInOut} button zooms out by an amount shown in the +\cs{amtShift} field; shift-clicking will zoom in by the amount shown +in the \cs{amtShift} field. The parameters are the same as for +\cs{funcInputField}, the descriptions are the same. + +\paragraph*{Setting the default values.} As with the required controls, the optional ones +can be given default values through convenience macros. + + +\takeMeasure{\string\defaultShiftAmt\darg{\meta{positive\_number}}} +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\defaultShiftAmt{!meta(positive_number)} +\defaultShiftAmt{1} +\end{dCmd} +The \cs{defaultShiftAmt} is used to set the default value of the \cs{amtShift} field; the default +value is \cs{defaultShiftAmt\darg{1}}. + +The \cs{functionSelect} lists four curves and four plots. The text can be changed by +through the following text macros. Each command is followed by its default definition. +\takeMeasure{\string\afCurve\darg{\meta{name\_for\_curve}}} +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\afCurve{!meta(name_for_curve)} +\afCurve{Curve} +\afPoint{!meta(name_for_point)} +\afPoint{Point} +\afUnused{!meta(unused)} +\afUnused{--unused} +\end{dCmd} +The definitions values of \cs{afCurve} and \cs{afPoint} are the +target of several search using regular expressions. If the values of +\cs{afCurve} and \cs{afPoint} are too complex, the regular +expression search may fail. Try to keep these definitions to ASCII +characters. + +\subsection{Populate and Silent Linking} + +The previous section details the interactive mode, where the +\cs{graphScreen} is present with all its required controls, and +possibly some optional controls. Curves are generated purely through +the user interface, that is, the user enters data into the various +form fields, clicks the \cs{graphBtn}, and \textsl{voil\`{a}}, the +graph is drawn! + +In this section, the populate mode is discussed as well as silent mode. + +\subsection{Graphing with \texorpdfstring{\protect\cs{sgraphLink}}{\CMD{sgraphLink}}}\label{sgraphlink} + +The document author can prepare function/points to be graphed, along +with all the essential data needed to view the graph. For populate, +the graphing data populate the required text field, and is available +for the user then to manipulate. The population of an interactive +graphing screen is done though a special link, the \cs{sgraphLink}. +(The ``s'' in \cs{sgraphLink} stands for ``silent,'' but that was +before I made the design decision to have a populate mode.) + +The syntax for \cs{sgraphLink} is +\takeMeasure{\string\sgraphLink[\meta{appr}]\darg{\meta{graph\_key\_vals}}% +\darg{\meta{func{\upshape|}points}}\darg{\meta{text}}} +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\sgraphLink[!meta(appr)]{!meta(graph_key_vals)}{!meta(func(!upshape|)points)}{!meta(text)} +\end{dCmd} +\PD The command takes four parameters, the first is the usual +optional parameter that can be used to change the appearance of the +link. The others we present in detail. +\begin{description} + \item [\texttt{[\meta{appr}]}:] Key-value pairs that are used to change the appearance of the link. + \item [\meta{graph\_key\_vals}:] Key-value pairs, some of which are used on the {\LaTeX} side, + some on the PDF side, while others on SWF side. + \begin{description} + \item\texttt{graph=\meta{value}}: The value of this key determines which + \emph{chart series} (FLEX terminology) the data will appear + on. The values of this key are: + \begin{description} + \item [\texttt{c1}, \texttt{c2}, \texttt{c3}, and \texttt{c4}:] + Use one of these values to graph a function, a polar function, + or a set of parametric functions. Up to four curves can be displayed + on the graphing screen at once. These values are displayed using + the \texttt{LinearSeries} (FLEX terminology). + \item [\texttt{a1}, \texttt{a2}, \texttt{a3}, and \texttt{a4}:] + Same as above, but the region between the horizontal axis, and + the graph is shaded in. These values are displayed using + the \texttt{AreaSeries} (FLEX terminology). + \item [\texttt{p1}, \texttt{p2}, \texttt{p3}, and \texttt{p4}:] + Use one of these values to plot points. These values are displayed using + the \texttt{PlotSeries} (FLEX terminology). + \end{description} + Thus, \texttt{graph=c2} tells the graphing + routines of {\AcroFLeX} and the {\AcroFLeX} Graphing widget + to display this data on series \texttt{c2}. + + If two curves or plots have the same value for + \texttt{graph}, then the one graphed last will + overwrite the earlier one. If you want both curves + or plots to appear on the graph together, give them + different \texttt{graph} values. + + When this key is not given a value, the default is + \texttt{c1}. + + \item [\texttt{type=\meta{\upshape{cart|para|polar}}}:] This key declares the type of curve, + possible values are \texttt{cart}, \texttt{para}, and + \texttt{polar}. This key is used mostly internally, and is + normally not used. There is one situation that it is used. When + defining a polar function, use \texttt{type=polar}. Thus, to + define a polar function, type something like this: + +\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\footnotesize] +\sgraphLink{type=polar,xInterval={[-1.5,1.5]},yInterval={[-1,2]}, + tInterval={[0,2*PI]},points=40,populate} + {1+sin(t)}{$r = 1 + \sin(\theta)$ } +\end{Verbatim} + + Note the explicit use of \texttt{type=polar}; the + parsing can identify a function of $x$ and a set of + parametric equations that are function of $t$, but help + is needed for polar. + + \item [\texttt{populate=\meta{\upshape{true|false}}}:] Possible + values are \texttt{true} or \texttt{false}, typing + \texttt{populate} is the same as \texttt{populate=true}. This + switch signals the graphing routines on the PDF side to populate + the required fields with the graphing data. The default is + \texttt{populate=false}, do not populate, use silent mode. + + \textbf{Populate versus Silent Modes:} The \texttt{populate} key + is how populate mode is distinguished from silent mode: + \texttt{populate=true} is populate mode, while \texttt{populate=false} + (or the populate parameter not listed) is silent mode. In + populate mode, the target graphing screen must have all required + control fields; in silent mode, the only control should be the + \cs{graphClrBtn} button. + + \item [\texttt{connectwith=\meta{\upshape{curve|segment}}}:] The key + determines the method used to connect consecutive points on the + graph, possible values are \texttt{curve} and \texttt{segment}. + This value is passed to the {\AcroFLeX} graphing widget. For + function of $x$, the default is \texttt{curve}; otherwise, the + default is \texttt{segment}. This value is ignored when the + \texttt{graph} property signals plotting + (\texttt{p1}--\texttt{p4}). + + \item [\texttt{points=\meta{num}}:] The number of points to generate for + plotting the current function. When the \texttt{graph} + property signals plotting (\texttt{p1}--\texttt{p4}), the + \texttt{points} property is ignored. If the graph property + signals graphing (\texttt{c1}--\texttt{c4}; + \texttt{a1}--\texttt{a4}), and argument \texttt{\#3} is a + set of rectangular points, the \texttt{points} property must + either not be present, or set to zero (\texttt{points=0}). + + \item [\texttt{xInterval=\darg{[a,b]}}:] (Required) An interval on the $x$-axis, the + interval must be in the form \verb!{[a,b]}!, for example, + \texttt{xInterval=\darg{[0,1]}}. For functions of $x$, this interval + represents the domain over which the function is graphed. It + also represents the left and right boundaries of the graphing + window. + + \textbf{Important:} The \texttt{xkeyval} package + parses these parameters. Because the interval notation + contains a comma (,), the whole interval must be enclosed in + braces so the parsing will be correct, as illustrated above. + + \item [\texttt{yInterval=\darg{[a,b]}}:] (Required) An interval on the $y$-axis, the + interval must be in the form \verb!{[a,b]}!, for + example, \verb!yInterval={[0,1]}!. It represents + the upper and lower boundaries of the graphing window. + + As with \texttt{xInterval}, the interval needs to be + enclosed in braces. + + \item [\texttt{tInterval=\darg{[a,b]}}:] When plotting a set of parametric equations, or + a polar function, this interval is required as a parameter. The + interval is of the form \verb!{[a,b]}!, including the braces, + and represents the domain of the parameter. The + \texttt{tInterval} must not be included otherwise, that is, for + graphing a function of $x$. Some early {\LaTeX} parsing tests + whether the value of \texttt{tInterval} is empty (the default) + or not. If nonempty, we assume the graphing is parametric or + polar. For point plotting, \texttt{tInterval} must not be + included in the parameter list. + + \item [\texttt{xPlot=\darg{[a,b]}}:] The parameter \texttt{xInterval} determines + the left and right boundaries of the graphing window; it also + determines the interval over which the function is to be plotted. + The \texttt{xPlot} separates these two functionalities; the value + of \texttt{xPlot} is an interval \verb![a,b]!, over which the + function will be plotted. Thus, \verb!xInterval={[-2,2]}! specifies + the scaling of the x-axis; while \verb!xPlot={[0,1]}! defines + the interval to plot the given function. If \texttt{xPlot} is not + specified, then \texttt{xInterval} will be used. + + \item [\texttt{noquotes=\meta{\upshape{true|false}}}:] When argument \texttt{\#3} is parsed, it + is, by default, placed in double quotes, for example, + \verb!"x^2"!; however, there are some situations where the + double quotes should not be used. (See the \texttt{afgraph.tex} + file for one such example.) Possible values for + \texttt{noquotes} are \texttt{true} and \texttt{false}. + Including \texttt{noquotes} in the option list is equivalent to + \texttt{noquotes=true}. The default is \texttt{noquotes=false}. + + \item [\texttt{wait=\meta{\upshape{true|false}}}:] Including + \texttt{wait} in the option list is equivalent to + \texttt{wait=true}. The default is \texttt{wait=false}. When + using \cs{defineGraphJS} to create a Java\-Script action that will + execute multiple calls to \texttt{Graph\_xy} or + \texttt{Graph\_xyt}, list \texttt{wait} in the option list. This + will cause a slight delay that allows the graphing screen to + become activated, (if not already activated) before the graphing + data is created and sent to the {\AcroFLeX} graphing widget. See + the example below in + \hyperref[defineGraphJS]{Section~\ref*{defineGraphJS}}, + page~\pageref*{defineGraphJS}. + \end{description} + \item [\meta{func{\upshape|}points}:] This argument can be a function or a set of points. + \begin{description} + \item [\meta{func}:] A function can be three types: (1) a function of $x$; (2) + a function of $t$; and a pair of function of $t$. If there is a + single function of $t$, case (2), that is interpreted as a polar + function, and graphed accordingly. The pair of functions must be + functions of $t$ and separated by a semi-colon (;); these are + then interpreted as a set of parametric equations. For example, + \verb!x^2! would be graphed as a parabola; \verb!1+sin(t)! would + be graphed as a Cardioid in the polar coordinate system; and + \verb!cos(t);sin(t)! would be graphed as a circle. + + \item [\meta{points}:] Points can be input as a semi-colon-delimited list of + rectangular coordinates. For example, \verb!(1,2);(2,3);(5,6)!. + Points can be plotted discretely, or plotted and connected with + either a smooth curve, or line segments. + \end{description} + \item [\meta{text}:] The text that the link is attached to, when + this text is clicked, the defined action of populating the graph + occurs. +\end{description} + +\subsection{Graphing with \texorpdfstring{\protect\cs{defineGraphJS}}{\CMD{defineGraphJS}}}\label{defineGraphJS} + +The \cs{defineGraphJS} command expands to either +\texttt{Graph\_xy()} or \texttt{Graph\_xyt()}, and is essentially +the code used by \cs{sgraphLink}. Use \cs{defineGraphJS} to create a +custom link action or form field action to graph pre-packaged +functions. + +\takeMeasure{\string\defineGraphJS\darg{\meta{graph\_key\_vals}}\darg{\meta{func{\upshape|}points}}\darg{\meta{command}}}% +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\defineGraphJS{!meta(graph_key_vals)}{!meta(func(!upshape|)points)}{!meta(command)} +\end{dCmd} + +\CmdDescription \cs{defineGraphJS} defines a new command +\cs{\meta{command}} what will expand to \texttt{Graph\_xy()} or +\texttt{Graph\_xyt()} fully populated by its arguments. This command +can be used to create new actions that involve multiple calls to the +{\AcroFLeX} graphing routines. + +\PD There are three required parameters. +\begin{description} + \item [\meta{graph\_key\_vals}:] The same key-value pairs as + described for \cs{sgraphLink}. + \item [\meta{func{\upshape|}points}:] An expression representing a + function of $x$, a polar function of $t$, a set of parametric + equations, or a set of points. + \item [\meta{command}:] A command that this JavaScript code will + be saved under. +\end{description} + +An example of usage can be found in \texttt{afgraph.tex}, we +present another example here, also included in \texttt{afgraph.tex}, that +might suggest the value of this command. We construct a link that +graphs a function and plots discrete points. + +\begin{Verbatim}[fontsize=\footnotesize,xleftmargin=\amtIndent] +\def\DomX{[0,2PI]}\def\DomY{[-1,1]} +\defineGraphJS{graph=c1,wait,xInterval={\DomX},yInterval={\DomY}, + points=40}{sin(x)}{\mySineCurve} +\defineGraphJS{graph=p1,wait,xInterval={\DomX},yInterval={\DomY}} + {(0,sin(0));(PI/2,sin(PI/2));(PI,sin(PI));(3PI/2,sin(3PI/2)); + (2PI,sin(2PI))}{\mySinePoints} +\setLinkText[\A{\JS{% + \clearGraphJS\r + \mySineCurve\r + \mySinePoints +}}]{Consider the sine function and indicated points}% +\end{Verbatim} +Note the use of the \texttt{wait} key in both the definitions to give the graphing screen +time to be activated and ready to receive data. Observe also the list of points is given +in symbolic form, we let JavaScript calculate the values for us. + +The command \Com{clearGraphJS} is used to clear the graphing screen before new curves are written +to the screen. \cs{clearGraphJS} expands to the document JavaScript function that clears +the graphing screen. + +\section{Customizations} + +There are a number of English phrases that appear as tooltips or as +messages in alert dialog boxes, as a result, the acroflex package has +a language option. +\takeMeasure{\string\usepackage[lang=english|german]\darg{acroflex}}% +\begin{dCmd}[commandchars=!()]{\wd\webtempboxi+2\fboxsep+2\fboxrule} +\usepackage[lang=english|german]{acroflex} +\end{dCmd} +Specifying \texttt{english} as the value of \texttt{lang} inputs the +file \texttt{afcustom\_us.def}, which normally does nothing; the +definitions made in this file are the hard-wired defaults of the +package. As an English speaker, you can edit this file, and improve +the phrasing, if you wish. Specifying \texttt{german} as the value +of \texttt{lang} inputs the file \texttt{afcustom\_de.def}; you can, +of course, edit this file to get a preferred phrasing. If not lang +key-value pair is specified, the \textsf{acroflex} package inputs +the file \texttt{afcustom.def} (found in the examples folder). This +file is intended for local use. Place it in the folder where the +source file resides, modify it as desired to get custom messages. +The file \texttt{afcustom.def} contains some instructions and guidelines for editing. + +\redpoint If the file \texttt{afcustom.def} is placed on the latex search +path, it will be found and input for each source file; if +\texttt{afcustom.def} is in the source file folder, it is this +version that is found first and input. +Should the phrases entered in \texttt{afcustom.def} require special +accents, use the \texttt{unicode} option of \pkg{web} (which just +passes the \texttt{unicode} option on to \pkg{hyperref}), and enter any +special characters using {\LaTeX} notation. For example, to address +my formerly favorite friend, J\"{u}rgen, we can write, +\begin{Verbatim}[xleftmargin=\amtIndent] +\ttgraphBtn{J\"{u}rgen, press to graph the function} +\end{Verbatim} +For the alert box messages, use JavaScript unicode notation, for example +\begin{Verbatim}[xleftmargin=\amtIndent] +\flJSStr{\af@badNumberMsg}{% + J\u00FCrgen, the value input does not appear to be a number, + please enter a number, or an expression that evaluates to a + number. \dps} +\end{Verbatim} +This latter example does not require the \texttt{unicode} option. + + +\newtopic Note that \cs{flJSStr} is a new command (defined in \pkg{insdljs}) that enables you +to enter unicode, for example, \cs{u00FC} is the u-umlaut (\verb!\"{u}! or +\"{u}). Also, within the argument string, you can use \cs{r} (carriage +return) and \t (tab) to format your lines as needed. Double backslash +\verb!\\! is converted into single backslash \verb!\!, so for example, +\verb!\\AcroTeX! appears in the dialog box as \cs{AcroTeX}. The string +argument is immediately expanded, so a command like \cs{dps} (in the above +definition) gets expanded at definition time. Use \cs{protect} to delay the +expansion until the tex compiler finally expands the JS command string +(useful here, if \cs{dps} gets redefined). + + + +\bigskip\noindent +That's all for now, I simply must get back to my retirement. \dps + +\end{document} + + +\newpage +\leftskip20pt\rightskip20pt\small +\addcontentsline{toc}{section}{\protect\numberline{}Index} +\markright{Index} +\printindex diff --git a/texmf-dist/source/latex/acroflex/swf/AcroFleX.swf b/texmf-dist/source/latex/acroflex/swf/AcroFleX.swf Binary files differnew file mode 100644 index 00000000..d13cc494 --- /dev/null +++ b/texmf-dist/source/latex/acroflex/swf/AcroFleX.swf |