summaryrefslogtreecommitdiff
path: root/graphics/figput/figput-manual
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-07-23 03:01:02 +0000
committerNorbert Preining <norbert@preining.info>2022-07-23 03:01:02 +0000
commitfcd380d0a9f42e14bfc55d8ea92e93fe0b7b48b9 (patch)
tree7db30c9583c625a81c7aabaecdbc163379b8a39a /graphics/figput/figput-manual
parent72eecdf45fcf3f421668c6bdfbfe17141ce3edc1 (diff)
CTAN sync 202207230301
Diffstat (limited to 'graphics/figput/figput-manual')
-rw-r--r--graphics/figput/figput-manual/figput-manual.pdfbin0 -> 227833 bytes
-rw-r--r--graphics/figput/figput-manual/figput-manual.tex857
2 files changed, 857 insertions, 0 deletions
diff --git a/graphics/figput/figput-manual/figput-manual.pdf b/graphics/figput/figput-manual/figput-manual.pdf
new file mode 100644
index 0000000000..dc459e33bf
--- /dev/null
+++ b/graphics/figput/figput-manual/figput-manual.pdf
Binary files differ
diff --git a/graphics/figput/figput-manual/figput-manual.tex b/graphics/figput/figput-manual/figput-manual.tex
new file mode 100644
index 0000000000..2960aceff7
--- /dev/null
+++ b/graphics/figput/figput-manual/figput-manual.tex
@@ -0,0 +1,857 @@
+
+\documentclass[10pt]{article}
+
+% Allows various tweaks to itemize as optional arguments.
+\usepackage{enumitem}
+
+% Gives the proof environment, with a box for QED.
+\usepackage{amsthm}
+
+% Needed for things like pmatrix.
+\usepackage{amsmath}
+
+% This allows footnotes from within array environment.
+\usepackage{footnote}
+\makesavenoteenv{array}
+
+% To adjust font sizes more easily.
+\usepackage{relsize}
+
+% This allows \verb in footnotes
+\usepackage{fancyvrb}
+
+% This allows me to say
+% \begin{figure}[H]
+% to mean ``here, and don't argue.'' Note the captial 'H'.
+\usepackage{float}
+
+% This is the modern thing to do, but the manual is 1300 pages!
+\usepackage{tikz}
+\usepackage{pgfplots}
+
+
+\begin{document}
+
+% Need this for fancyvrb to work.
+\VerbatimFootnotes
+
+% So that I don't have to type this all the time.
+\newcommand{\figput}{\textsc{FigPut}}
+
+
+\begin{center}
+ {\Large \figput}
+
+ Interactive Figures for \LaTeX
+
+ \verb=https://github.com/rsfairman/figput=
+
+ Randall Fairman
+
+ Version 0.90, July 21, 2022
+\end{center}
+
+\vskip 0.2cm
+
+The \textsc{FigPut} system allows \LaTeX\ to produce interactive
+figures. The system produces a static PDF file, as usual; in addition,
+the document can be viewed with an Internet browser and the figures
+become interactive. See the prototype in {\tt example/example.tex}
+to clarify what follows.\footnote{The version available on CTAN
+includes only what is strictly necessary to rebuild the document from
+scratch: {\tt example.tex} and {\tt exteernalcode.js}. The repository at {\tt
+ github} includes all the files that result from the build process,
+and are necessary to view the PDF in either static or interactive
+form.} To view this example in its fully interactive form, see
+\verb=rsfairman.github.io/figput-example/=.
+
+% For some reason \textsc doesn't work within \section
+\section{Why \normalfont\scshape{FigPut}}
+
+There are many ways to produce figures in \LaTeX: MetaPost, TikZ,
+PSTricks, XY-pic, {\tt graphics}, {\tt picture}, and more. Creating
+technical figures is often an exercise in programming, and none of
+these is based on a commonly used programming
+language. \textsc{FigPut} is based on JavaScript (JS), which is
+probably the most widely used language today. Moreover,
+\figput\ allows figures to be animated and/or interactive.
+
+Aside from the fact that figures are specified with
+JavaScript, the system is normal \LaTeX. An important feature is that
+the two forms of the document -- static PDF and interactive -- look
+identical, with the same pagination and formatting. The reader can
+move between the printed version and the interactive version without
+needing to reorient.
+
+% For some reason \textsc doesn't work within \section
+\section{Using \normalfont\scshape{FigPut}}
+
+Here's a list of all the commands available in \figput:
+\begin{verbatim}
+\begin{figput} ... \end{figput}
+\FigPut
+\SetInnerMargin
+\SetOuterMargin
+\NeverSkip
+\AllowSkip
+\LoadFigureCode
+\end{verbatim}
+
+\subsection{The \LaTeX\ Side}
+
+Interactive figures are specified with the {\tt figput}
+environment or the \verb=\FigPut= command. The full form of the
+environment specification is
+\vskip 0.2cm
+
+\noindent\verb=\begin{figput}{<fig_name>,<fig_ht>}[=\emph{optional arguments}\verb=]=
+
+\noindent\verb= <JavaScript code>=
+
+\noindent\verb=\end{figput}=
+\vskip 0.2cm
+
+\noindent There are two mandatory arguments: \verb=<fig_name>= and
+\verb=<fig_ht>=. Every figure must have a unique name. This name is
+unrelated to any \verb=\label= or other identifier used for
+the figure. The \verb=<fig_ht>= is the height of the figure, expressed
+like other \LaTeX\ lengths in {\tt pt}, {\tt cm}, \emph{etc}. The
+figure is allocated this much vertical space on the page. The
+remaining optional arguments are discussed below.
+
+The {\tt <JavaScript code>} is used to draw the figure, and the only
+requirement is that it be given as
+\begin{verbatim}
+function <fig_name>(ctx) {
+ ...
+}
+\end{verbatim}
+The name of the JS function must match the figure name given to the
+{\tt figput} environment -- that's how the browser finds the correct
+JS function to draw a particular figure. The {\tt ctx} argument
+is required; it's the ``rendering context'' used for
+drawing.\footnote{\label{page-ctx} A variable of this type is commonly obtained in
+JavaScript by something like \vspace{-1.5mm}
+\begin{verbatim}
+let canvas = document.getElementById('where-drawing-happens');
+let ctx = canvas.getContext('2d');
+\end{verbatim}
+\vspace{-1.5mm} The full name for this type is {\tt
+ CanvasRenderingContext2D}.}
+
+All of the JS functions for the various figures share the same
+name-space, and it is perfectly acceptable to share functions between
+figures or to define helper functions within a figure's
+environment. If many figures use the same {\tt drawDoodad()}
+function, then that function should appear with only a single figure, and
+it will be available to all of them.
+
+Use \verb=\SetInnerMargin= and \verb=\SetOuterMargin= to set the inner and outer
+margins (which may differ in a book that has left and right
+pages). The figure will be rendered within a rectangle that is set in
+from the left margin by the given amount. For example, you might say
+\begin{verbatim}
+\SetInnerMargin{150pt}
+\SetOuterMargin{150pt}
+\end{verbatim}
+so that the left edge of the figure is {\tt 150pt} from the left edge
+of the paper. These values can be changed before every figure, if that
+is appropriate.
+
+The coordinate system used within the JS code is based on big points ({\tt
+ bp}), with the origin at the lower-left corner of the
+figure. The $y$-coordinate increases as you move \emph{up} the page.
+The $y$-axis is offset from the edge of the page by the
+value given to \verb=\SetInnerMargin= or \verb=\SetOuterMargin=.
+
+There is no need to begin the drawing by erasing the drawing
+area. That's done automatically.
+
+\subsubsection*{Optional Arguments}
+
+The arguments to {\tt figput} in {\tt []}, are optional. The first two
+of these arguments are \label{ht-above-below}
+\begin{verbatim}
+ht_above, ht_below
+\end{verbatim}
+If these arguments appear, then they must both appear, they must be
+the first two arguments, and they must be given in that order (above,
+then below); furthermore, they must include a unit specification, like {\tt
+ bp}. An interactive figure may need a bit of extra clearance
+for an animation or space for widgets that aren't part of the
+figure itself. The static version of the document always uses
+\verb=<fig_ht>= for the figure height, while the interactive form adds
+this optional amount of space above and below the figure. If
+\verb=ht_below= is non-zero, then the $y$-axis is \verb=ht_below=
+above the bottom of the figure when drawn interactively.
+
+The remaining optional arguments may appear in any order and function
+as boolean flags:
+
+\begin{itemize}[itemsep=-1pt,leftmargin=2cm]
+ \item[{\tt nostatic}] Use this when the figure is to be shown only
+ when the document is viewed interactively. No figure will appear
+ in the PDF. Almost certainly, the mandatory \verb=fig_ht= argument
+ should be zero. The sum of \verb=ht_above= and \verb=ht_below= is
+ used for the height of the interactive figure.
+ \item[{\tt done}] indicates to the browser that the {\tt .tikz}
+ should not be updated.
+ \item[{\tt skip}] TikZ files can be large and take a long time to
+ process. When this is set, the TikZ file won't be loaded and the
+ figure will appear with a default ``not available'' message.
+\end{itemize}
+
+When the composition of a figure is complete, it often makes sense to
+turn on the {\tt done} and {\tt skip} flags. Using {\tt skip} saves
+time, and {\tt done} prevents inadvertent overwriting of a {\tt .tikz}
+file that you're happy with. However, to see the complete output, with
+your figures, you would have to go back and tediously remove all of
+the {\tt skip} flags. Use \verb=\NeverSkip= to avoid that tedium and
+disable all the {\tt skip}
+flags that occur until the next \verb=\AllowSkip=.
+
+\subsection*{The {\tt \textbackslash FigPut} Command}
+
+\verb=\FigPut= takes exactly the same arguments as the {\tt figput}
+environment, but the JS code must appear in an external file. The
+location of this external file is indicated with
+\verb=\LoadFigureCode=. If the code is found in {\tt mydrawcode.js},
+then
+\begin{verbatim}
+\LoadFigureCode{mydrawcode.js}
+\end{verbatim}
+must appear somewhere in the {\tt .tex} file.
+
+It is often easier to use an external file to consolidate the drawing
+code in fewer files (or a single file). Not only
+does it make the {\tt .tex} file shorter and easier to navigate, but it
+allows the use of programming tools tailored to JS. For instance,
+the code could be written in TypeScript and compiled to JS. On the other
+hand, if the code for the figures is brief, then it may be clearer and more
+direct to use the {\tt figput} environment so that the code is in the
+{\tt .tex} file.
+
+\subsubsection*{Additional Remarks}
+
+There is no explicit provision in \textsc{FigPut} for changing the
+body of the text based on whether the document is to be viewed statically
+or interactively. This is intentional. The aim is for the text and its
+layout to be \emph{identical} in the two scenarios. However, it would
+be relatively straightforward to set up a couple of commands like
+\begin{verbatim}
+\newcommand{\statictext}[1]{#1}
+\newcommand{\intereactivetext}[1]{ }
+\end{verbatim}
+In the above example, anything that appears in \verb=\statictext{}=
+will pass through to the \LaTeX\ document, while everything in
+\verb=\interactivetext{}= will be ignored. Swap these two definitions
+depending on whether the document is being compiled for interactive or
+static reading.
+
+\subsection{Workflow}
+
+There are several phases to composing and releasing a document. The
+first phase is a loop through writing the \LaTeX, compiling it, viewing
+the output in a browser and generating TikZ, until the document is
+done. Everything in the first phase is local to your machine. The
+second phase is posting the result to a public-facing website. The
+first phase is discussed here; see Section \ref{sec-distributing} for
+the second phase.
+
+\subsubsection*{Setup}
+
+The functionality of \figput\ is given by {\tt figput.sty}. It
+requires the following packages: {\tt zref}, {\tt xsim}, {\tt tikz}
+and {\tt verbatim}.
+
+A typical arrangement is to have a {\tt javascript}
+directory with the files for the browser side of the framework, and a
+\LaTeX\ directory where the document is written in the usual way. The {\tt
+ javascript} directory contains the JS files and the one HTML file needed
+to provide the browser front-end, and you'll also find {\tt server.py}.
+This Python script runs a local server so that your browser can
+open and view the document being written.\footnote{This requires
+Python 3 -- although that's probably obvious these days.} In principle, it's no
+different than a normal web-server, but it is tailored in several
+ways to the task at hand. To invoke this server, use the command-line
+to go to the {\tt javascript} directory and type
+\begin{verbatim}
+python server.py directory/nameof.pdf [port_num]
+\end{verbatim}
+The {\tt directory/nameof.pdf} argument is required and should be the
+path from the current ({\tt javascript}) directory to the PDF being
+generated by \LaTeX. Often, this will be something like
+\begin{verbatim}
+../../latex_area/num_theory/hairy_math.pdf
+\end{verbatim}
+The optional \verb=port_num= argument indicates the TCP/IP port on which the
+server will listen. It defaults to 8000. In principle, any integer in
+the range $[0,2^{16})$ could appear here, but certain values are
+restricted and others may already be in use. Stick to values
+in the range 8000-8100, and you should be safe.\footnote{See
+\verb=en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers=}
+
+By using different port numbers, it's possible to run several servers
+at once, so that multiple documents can be viewed and edited at the
+same time. Once the server is running, point your browser to
+\verb=localhost:8000= (or whatever \verb=port_num= you've chosen) to
+load the document.
+
+As stated, {\tt server.py} differs from a normal web-server in certain
+ways. This is done to make it easier to work with a document while it
+is being written. Once the document is complete, it can be served by a
+normal web-server.
+
+\subsubsection*{Additional Files}
+
+There are two additional directories in the {\tt javascript} directory:
+{\tt development} and {\tt release}. \figput\ was written in
+TypeScript, and the {\tt .ts} files are in {\tt development}. Even if
+you don't want to modify the system, the TypeScript files are easier
+to follow than the JavaScript files, and are the first place to look to
+clarify how the system works internally. There are four files:
+\begin{itemize}[itemsep=-1pt,leftmargin=1cm]
+\item{\tt main.ts} is the main entry-point for the program. This is
+ unlikely to interest anyone who wants to simply use \figput.
+\item{\tt layout.ts} handles page layout -- also uninteresting to most people.
+\item{\tt widgets.ts} has the code for the various widgets. If widgets
+ aren't acting the way you expect, then look here.
+\item{\tt tikz.ts} handles lower-level geometry, and conversion from
+ JS to TikZ. Look here for details about the {\tt Point2D} and
+ {\tt FPath} classes.
+\end{itemize}
+
+Two files found in the {\tt javascript} directory are {\tt
+ pdf.worker.min.js} and {\tt pdf.js}. These are the source files for
+Mozilla's pdf.js library. The complete project can be found at
+\verb=github.com/mozilla/pdf.js=. The files are included here because,
+when developing a \LaTeX\ document on your local machine, it would be
+pointless (and slow) to download these files every time an updated
+version of your document is loaded.
+
+The {\tt release} directory contains the files to be used when the
+document is released to a public-facing website. As noted above, {\tt
+ server.py} works differently than a normal web-server. The release
+process is discussed in more detail in Section \ref{sec-distributing}.
+
+\subsubsection*{From JavaScript to TikZ}
+
+Once the server is running, a browser can view documents created with
+\figput, but the figures will not be visible in
+the PDF document until a TikZ file is provided. The \emph{Get TikZ}
+button in the browser window generates the TikZ files. The server
+will save these files to the same directory as the PDF file. Note that
+a TikZ file will only be generated if the figure has been scrolled
+into view (or nearly into view) since the document was loaded.
+
+Because TikZ files can take time to load, it's often useful to
+compose the figures one (or a few) at a time. Apply the optional
+{\tt done} argument for any figures that are complete, and the
+\emph{Get TikZ} button will not generate TikZ files for them. You may
+want a particular frame from an animation; once you have the right
+frame, it would be frustrating to accidentally overwrite it in the course of
+working on some other figure. Using {\tt done} prevents that from happening.
+
+\subsection{JavaScript Drawing}
+
+In most respects, any JS code can be used with FigPut, but it must be
+possible to translate the JS drawing commands to TikZ, and that leads
+to certain requirements. In a nutshell, all drawing must be done using a
+class that is very similar to JS's built-in {\tt Path2D} class.
+
+If this is too restrictive, then it is possible to side-step the
+requirement with a bit of extra effort. If you use JS drawing commands
+that are off-limits, like {\tt drawImage()}, then the interactive version
+will work fine, but you'll have to find some other way to generate the
+figure for inclusion in the static PDF. Any of the usual methods of
+generating figures for \LaTeX\ documents will work, but now the two
+versions, interactive and static, are generated from different
+source-code.
+
+Earlier, in a footnote on p. \pageref{page-ctx}, it was a stated that
+the {\tt ctx} argument to your drawing function has the standard JS type, {\tt
+ CanvasRenderingContext2D}. That's not always true. Any drawing
+done \emph{to the browser} is \emph{precisely} an object of this
+type. If you only care about seeing your document within the browser
+framework, and you don't care about generating figures for a
+standalone {\tt .pdf} file, then that's all you need to know. Draw
+with JS however you like.
+
+To produce TikZ output, the built-in {\tt CanvasRenderingContext2D}
+must be ``spoofed.'' All of the drawing commands that normally go to
+the built-in JS browser code go to \figput's {\tt CTX} class
+instead, where they are converted to TikZ output.
+This class implements a sub-set of the full list of drawing
+commands normally available. The permitted commands are
+\begin{verbatim}
+ ctx.fill()
+ ctx.stroke()
+ ctx.lineWidth
+\end{verbatim}
+These work almost as they normally do. The {\tt lineWidth} is the
+thickness of any paths, and can be thought of as being in \TeX's {\tt
+ bp} units. The {\tt fill()} and {\tt stroke()} commands normally
+take a JS {\tt Path2D} object, but you should pass an object of type
+{\tt FPath} instead.
+
+The methods of {\tt FPath} listed below are exactly like those found
+in {\tt Path2D}. They add a new segment to an existing {\tt FPath},
+obtained with {\tt new}. See any JS resource for an explanation.
+\begin{itemize}[itemsep=-1pt,leftmargin=*]
+\item {\tt closePath()}
+\item {\tt moveTo()}
+\item {\tt lineTo()}
+\item {\tt bezierCurveTo()}
+\item {\tt ellipse()}
+\end{itemize}
+And these methods of {\tt FPath} are new -- they have no counterpart
+in {\tt Path2D}.
+\begin{itemize}[itemsep=-1pt,leftmargin=*]
+\item {\tt addPath(p)} appends the {\tt FPath}, {\tt p}, to an
+ existing {\tt FPath}.
+\item {\tt translate(p)} translates an {\tt FPath} by the given {\tt Point2D}.
+\item {\tt rotate(angle)} rotates an {\tt FPath} by the given angle,
+ in radians.
+\item {\tt scale(s)} scales an {\tt FPath} by the given factor
+ (relative to the origin).
+\item {\tt reflectX()} reflects an {\tt FPath} across the $x$-axis.
+\item {\tt reflectXY()} reflects an {\tt FPath} across the $x$ and $y$-axis.
+\item {\tt rotateAbout(angle,p)} rotates a given {\tt FPath} about the
+ given {\tt Point2D} by the given angle.
+
+The methods above apply to an existing {\tt FPath} and return a new {\tt FPath}.
+\item {\tt parametricToBezier(f,t0,t1,n)} converts a parametric
+ function, {\tt f(t)}, to a path consisting of {\tt n} B\'ezier
+ curves as {\tt t} runs from {\tt t0} to {\tt t1}. The function
+ must be defined to return {\tt Point2D} objects.
+
+This is a static method, so it returns a new {\tt FPath} that is unrelated to any existing {\tt FPath} objects.
+\end{itemize}
+There are several additional methods in {\tt FPath} that may be
+useful, but they haven't yet been tested well enough to mention
+here (and they may change in the future). See the source code if
+you're adventurous.
+
+Several of the methods above mention the {\tt Point2D} class, and it's what you would expect. Use
+\begin{verbatim}
+ new Point2D(x,y);
+\end{verbatim}
+to create these objects. There's a long list of methods defined in the
+class: {\tt translate()}, {\tt rotate()}, {\tt length()},
+\emph{etc}. See the source code for a complete list.
+
+Text is drawn in a way that is further from how it's normally done in
+JS. Instead of calling {\tt ctx.fillText()}, there are three top-level
+functions (not part of any class) for drawing text:
+\begin{verbatim}
+ drawText(ctx,txt,x,y,dx,dy);
+ drawTextBrowserOnly(ctx,txt,x,y,dx,dy);
+ drawTextTikZOnly(ctx,txt,x,y,dx,dy);
+\end{verbatim}
+The arguments are the same in the three cases, but the first function will draw
+text to both the browser window and the TikZ, while the other two will
+draw the text to only one destination or the other. The {\tt ctx} is
+the same as the argument to your drawing function, {\tt txt} is the
+string to be drawn, {\tt x,y} is the location of the text \emph{for
+the browser}, relative to the lower-left corner of the
+bounding-box. When the text is drawn to TikZ, it is drawn at {\tt
+ x+dx,y+dy}. Because the fonts used in the browser and in TikZ differ
+slightly, sometimes it's necessary to tweak the TikZ placement. Setting
+\begin{verbatim}
+ ctx.font = '10px san-serif';
+\end{verbatim}
+sets the browser font to something very close the default font used
+by TikZ, but it's not a perfect match. The {\tt dx} and {\tt dy}
+arguments are optional and default to {\tt 0}.
+
+As a bonus, the static method, {\tt Numerical.newton()}, can be used to
+solve $f(x) = y$ for $x$, given $y$. It's a naive implementation of Newton-Raphson.
+
+\subsection{JavaScript Widgets}
+
+The foregoing framework could be used an an alternative to TikZ,
+PSTricks, MetaPost, \emph{etc.}, if your aim is strictly static
+output. To make the figures interactive, there must be some means to
+accept user input -- widgets.
+
+All widgets have a static {\tt register()} method. Do not use {\tt
+ new} to create widgets! Registering a widget has the effect of
+making it available for user input, and drawing it too (with one
+exception). The arguments to these {\tt register()} methods vary with
+the widget, but the first argument is always the {\tt ctx} known to
+the drawing function, and the last argument is always a {\tt name} (a
+string). One drawing could have several widgets of the same kind and
+{\tt name} is used to distinguish
+them. So, if a particular drawing has three buttons, then they could
+be created/registered with
+\begin{verbatim}
+let b1 = ButtonWidget.register(ctx,...,"first");
+let b2 = ButtonWidget.register(ctx,...,"second");
+let b3 = ButtonWidget.register(ctx,...,"third");
+\end{verbatim}
+These names only need to be unique within a single drawing and one
+type of widget. So, in the example above, two {\tt
+ DraggableDotWidget}s could be registered in the same drawing as
+the {\tt ButtonWidget}s with
+\begin{verbatim}
+let dd1 = DraggableDotWidget.register(ctx,...,"first");
+let dd2 = DraggableDotWidget.register(ctx,...,"second");
+\end{verbatim}
+
+\subsubsection{\tt ButtonWidget}
+
+These are registered with
+\begin{verbatim}
+ButtonWidget.register(ctx,x,y,text,name);
+\end{verbatim}
+The {\tt x,y} argument is the location of the button, relative to the
+lower-left corner. The {\tt text} is what is shown as the message
+within the button. Buttons work by calling back to your drawing code
+whenever they are clicked. Every time the button is clicked, the
+entire drawing function is executed.
+
+There are two useful fields of {\tt ButtonWidget}. If {\tt b} is a
+{\tt ButtonWidget}, then {\tt b.clickState} toggles between {\tt true} and {\tt
+ false} with every click of the button, while {\tt b.resetState} is
+set to {\tt true} whenever the button is clicked -- and remains {\tt
+ true} until your drawing code resets it.
+
+\subsubsection{\tt NumberInputWidget}
+
+This is similar to {\tt ButtonWidget}, and is used to input single
+numbers. It's registered with
+\begin{verbatim}
+NumberInputWidget.register(ctx,x,y,v,name);
+\end{verbatim}
+The {\tt v} argument is the initial numerical value shown in the
+widget. Whenever the user changes this value, the widget calls back
+and executes the entire drawing function. To obtain this value, call
+{\tt getValue()} on the relevant widget. Because this widget relies
+on HTML, {\tt getValue()} returns a string. It may be necessary to
+call the JS {\tt parseFloat()} or {\tt parseInt()} functions on this
+value.
+
+\subsubsection{\tt DraggableDotWidget}
+
+A ``draggable dot'' is a small dot that can be grabbed by the mouse
+and moved around. They're registered with
+\begin{verbatim}
+DraggableDotWidget.register(ctx,x,y,name);
+\end{verbatim}
+To determine where the user has moved a dot, refer to the widget's
+{\tt widgetX} and {\tt widgetY} fields.
+
+Most widgets are used ``off to the side'' and wouldn't normally
+interfere with the way the figure is drawn, but these dots are typically
+used as part of the drawing itself. The order in which dots are drawn
+may matter. Sometimes a dot should be drawn first, so that other
+elements of the figure may be drawn over it; and sometimes a dot
+should be drawn last so that nothing can obscure it. For this
+reason, unlike other widgets, registering the widget does not also
+draw the widget. An explicit call to the widget's {\tt
+ draw(ctx)} method must be made to draw the dot.
+
+\subsubsection{\tt DraggableDrawWidget}
+
+This is similar to {\tt DraggableDotWidget}, but it has no default
+drawing behavior. The user must provide functions to specify what is
+to be drawn. So it can also be a draggable polygon, or a draggable
+anything-you-can-draw. Register these with
+\begin{verbatim}
+DraggableDrawWidget.register(ctx,x,y,
+ drawFcn,drawSelFcn,testPosFcn,
+ name);
+\end{verbatim}
+The {\tt drawFcn} must be defined to take the {\tt ctx} as the sole
+argument. It can draw whatever it wants, noting that the origin is
+shifted so that drawing should typically take place relative to {\tt
+ (0,0)}, not {\tt (widgetX,widgetY)}. In most cases, this means
+that the drawing code is independent of where the item is on the
+page. {\tt drawFcn} must return an {\tt FPath} object to indicate
+the ``clickable area'' for the item. For example, if what is being
+drawn is a small square, then the function might be defined as
+\begin{verbatim}
+function drawSquare(ctx) {
+ let p = new FPath();
+ // p.lineTo, moveTo, etc., to make a square.
+ ctx.fillPath(p);
+ return p;
+}
+\end{verbatim}
+The value returned is noted, and any click in the interior of the path
+-- as determined by the JS function {\tt isPointInPath()} --
+is taken to be a valid click on the object, to select it and drag it around.
+
+The {\tt drawSelFcn} argument to {\tt register} is identical to the
+{\tt drawFcn} argument, but it is called to draw the item when it is
+``selected.'' Often, the only difference between the two functions
+will be the color used to draw the item.
+
+The {\tt testPosFcn} argument is used to determine whether a
+particular location for the item is acceptable. For example, an item
+could be limited to a particular region. This is called every time the
+mouse is moved, after the item has been selected, up until the mouse
+button is released. The function takes five arguments and returns a
+boolean. The five arguments are the proposed {\tt x,y} position (the
+mouse location), followed by the width of the drawing area, then the
+height above and below the $x$-axis, where the width is equal to the
+text width. Return {\tt true} if the
+proposed {\tt x,y} is acceptable; {\tt false} otherwise. At a minimum,
+the function should typically check that {\tt x,y} is inside the
+figure rectangle.
+
+\subsubsection{\tt LoopAnimWidget}
+
+This widget and the next one ({\tt OpenAnimWidget}) are for
+animations, and work similarly. A {\tt LoopAnimWidget} is used for
+animations that run in a repeating loop. There are many arguments to
+register them.
+\begin{verbatim}
+LoopAnimWidget.register(ctx,x,y,scale,visWidget,
+ steps,start,timeStep,
+ visSteps,visFastSlow,visPauseRun,visCircle,triGrab,
+ name);
+\end{verbatim}
+The {\tt x,y} values are the location of the center of the circle that
+is the primary element of the widget. The widget can be made larger or
+smaller by changing the {\tt scale} -- a value of {\tt 1.0} makes the
+circle 40~{\tt bp} in radius. The {\tt visWidget} argument is a
+boolean; set it to {\tt false} to run an animation without
+showing the user this widget.
+
+{\tt steps} is the integral number of steps that make up one loop of
+the animation. {\tt start} is the step on which the animation
+starts -- so that the animation starts with the {\tt start}-th
+frame. {\tt timeStep} is the number of milliseconds between
+frames. Unless the machine is \emph{very} fast, anything less than
+{\tt 10} for {\tt timeStep} is probably pointless, and a setting of
+{\tt 50} or {\tt 75} is more reasonable considering the human eye.
+
+The next group of arguments -- {\tt visSteps} through {\tt triGrab} -- are
+all booleans. They determine whether certain parts of the widget are
+visible. {\tt visSteps} shows or hides an area above the circle that
+can be used to change the number of steps taken per frame. The user
+can use this control to skip frames of the animation. {\tt
+ visFastSlow} is for some ``sideways chevrons,'' in an area below the circle,
+that allow the user to change the number of milliseconds per
+frame. {\tt vsPauseRun} is for a pause/run control below the
+circle. {\tt visCircle} is for the entire circle. The circle has a
+small grabable triangle to indicate which frame is being shown; use
+{\tt triGrab} to show or hide the triangle.
+
+To draw a particular frame from your drawing function, refer to the
+{\tt curStep} field of the object. This will be a value in the range
+from 0 to the {\tt steps} argument to {\tt register()}.
+
+\subsubsection{\tt OpenAnimWidget}
+
+This widget is for open-ended animations that don't run in a loop,
+but continue ``forever.'' Whereas {\tt LoopAnimWidget} indicates the
+frame being viewed relative to a circle, {\tt OpenAnimWidget} uses a
+bar, something like a scroll-bar. Registration is similar to
+{\tt LoopAnimWidget}:
+\begin{verbatim}
+OpenAnimWidget.register(ctx,x,y,scale,width,visWidget,
+ timeStep,decay,
+ visSteps,visFastSlow,visPauseRun,visBar,barGrab,
+ name);
+\end{verbatim}
+The {\tt ctx}, {\tt x}, {\tt y}, {\tt scale} and {\tt visWidget}
+arguments are as for {\tt LoopAnimWidget}. {\tt width} sets the width
+of the bar, in {\tt bp}.
+
+{\tt timeStep} is in milliseconds, as for {\tt LoopAnimWidget}. The
+{\tt decay} is used to adjust the rate of travel of the ``thumb'' along the
+bar as the animation progresses. Since the animation is potentially
+infinite, the thumb moves quickly early in the animation, then moves
+more and more slowly, so that it never quite reaches the end of the
+bar. The position of the thumb is given by
+$$1 - {1\over (1+{\tt decay})^s},$$
+expressed as a fraction of the bar's total length, where $s$ is the
+frame count (\emph{i.e.}, {\tt curStep}). A reasonable setting for {\tt
+ decay} is something in the range of $10^3$ to $10^6$, although it
+will depend on the animation.
+
+The arguments from {\tt visSteps} to {\tt barGrab} are all boolean and
+control which controls that make up the widget are visible. They're
+like their counterparts in {\tt LoopAnimWidget}, except that {\tt
+ OpenAnimWidget} uses a bar instead of a circle.
+
+\section{Distributing a Complete Document}
+\label{sec-distributing}
+
+The PDF document is no different than any other PDF, and can be
+distributed in the usual ways. When moving the document in interactive
+form to a public-facing website, a few steps are necessary.
+
+See the {\tt javascript/release} directory. It has two files: {\tt
+ figput.html} and {\tt figput.js}. The {\tt .js} file is just the
+four files used for the local version ({\tt main.js}, \emph{etc}.),
+consolidated to a single file and minified. These two files must
+appear on the web-server in the same directory as the various files
+that make up your document.
+
+{\tt figput.html} is only a few lines long, and there are two
+important changes that must be made. See the line that reads
+\vskip 0.2cm
+\noindent\verb!<body onload="doOpenDocument('unknown1',unknowny)" id="mainbody">!
+\vskip 0.2cm
+\noindent Change {\tt unknown1} to your document's name, \emph{without} the
+{\tt .pdf} suffix. If the document was generated from {\tt
+example.tex}, then {\tt unknown1} should be changed to {\tt example}.
+Second, change {\tt unknowny} to {\tt 0}. When the document is
+opened, this is the vertical position, in {\tt bp}, at which the document is
+opened. Setting {\tt unknonwy} to {\tt 0} means that the document
+will open at the top of the first page. Of course, it's possible
+that you want the document to open at some other location, in which
+case use some other value for {\tt unknowny}.
+
+The server needs {\tt figput.html} (after the modifications
+above), {\tt figput.js}, and the files that make up your
+document. These files consist of the {\tt .pdf} file, the {\tt .fig.aux}
+file, any {\tt .js} files referred to by \verb=\LoadFigureCode=, plus
+any {\tt .fjs} files generated by your document. The server does not
+need the {\tt .tikz} files.
+
+\section{Code Internals}
+
+An understanding of this section isn't necessary to use \figput; it's
+here to provide a bit of background for anyone who wants to improve
+or modify the framework. Most of \figput\ is in TypeScript, which
+should make it easier to follow.
+
+Throughout the various files that make up the system are
+{\tt BUG} annotations. These are not bugs \emph{per se}, but are more
+like infelicities, opportunities for improvement, or to draw attention
+to something confusing or problematic. If you want to contribute to
+\figput, then these are a good place to start.
+
+\subsection{\tt figput.sty}
+
+The {\tt .sty} file is well-commented and should be
+self-explanatory. However, I am far from an expert in \LaTeX3
+programming. Here is a high-level list of ways in which it might be
+possible to improve things.
+
+\begin{itemize}[itemsep=-1pt,leftmargin=*]
+\item {\tt figput.sty} is written for \LaTeX3. The entire thing might
+ be simpler if it were in Lua\TeX.
+\item The ability to explicitly specify the inner and outer margins
+ used by \figput\ (with \verb=\SetInnerMargin= and
+ \verb=SetOuterMargin=) is useful, but it would often suffice to
+ default to the margins used by \LaTeX. How can those values be
+ obtained?
+\item Someone who is more expert in \LaTeX3 could improve the code's
+ clarity and brevity.
+\item It would be nice if \figput\ could create figures within a {\tt
+ minipage}, but that would require extensive changes to both the
+ \LaTeX\ and browser code.
+\end{itemize}
+
+\subsubsection*{A Quirk}
+
+\LaTeX\ on Windows has a quirk. \TeX\ will not write to a
+file whose type is executable. Thus, it won't write to
+a {\tt .pl} file (Perl), {\tt .py} (Python) file, \emph{etc.},
+depending on how the machine is set up. \figput\ creates
+JavaScript files, which are typically saved as {\tt .js} files, and
+these may be seen as executable by Windows. Fortunately,
+browsers doesn't care what the suffix is, so \figput\ uses
+{\tt .jfs} as the suffix.
+
+This limitation on the file name suffix applies to \verb=\write=, but
+not to \verb=\write18=. \TeX\ is limited in this way to prevent
+accidental errors and for security. One solution might be to have the
+package write files using an acceptable suffix, then change the
+suffix with \verb=\write18=, which does not have this
+limitation. However, to use \verb=\write18= this way, \LaTeX\ would
+have to be invoked with something like
+\begin{verbatim}
+pdflatex -shell-escape
+\end{verbatim}
+which would be annoying.
+
+\subsection{\tt server.py}
+
+The server is a simple thing, so there's not much to say. It
+would be nice if it were written in a compiled language so
+that the user doesn't need to install Python.
+
+\subsection{Browser Code}
+
+This part is written in TypeScript (TS), which is essentially JS with
+type annotations. It must be translated
+to JS for the browser to run it, but TS code is easier to follow, and
+the type information heads off many programming errors.
+
+Although the program is (to my knowledge!) bug-free in the usual
+sense, there are plenty of {\tt BUG} annotations to draw attention to
+places where the code could be improved. Some of the higher-level
+possibilities for improvement are noted below.
+\begin{itemize}[itemsep=-1pt,leftmargin=*]
+\item \figput\ relies on the {\tt pdf.js} library for rendering
+ PDFs. The result is not as crisp as I would like. It's unclear
+ whether the problem is with the library itself, or how it is being
+ used. Someone who knows that library well may be able to improve the
+ output. Maybe a different library would work better.
+\item Most of the widgets do not rely on the DOM, but {\tt
+ NumberInputWidget} and {\tt ButtonWidget} are based on the built-in
+ DOM elements. It would be nice if these didn't use the DOM.
+\item Many additional widgets could be created.
+\item Adjust the font used for figures in the browser to make it more
+ nearly identical to what appears in the PDF.
+\item Color is entirely neglected on the \LaTeX\ end of \figput. Browser output
+ can be colored arbitrarily (with {\tt ctx.fillStyle} or {\tt
+ ctx.strokeStyle}, as usual), but the TikZ output is limited to
+ black and white.
+\item Double-buffer everything. Animations seem to run fine,
+ without any noticeable flicker, but double-buffering \emph{all}
+ drawing would put an end to any concerns about flicker.
+\item Animations should be turned off and stop generating events when
+ they are scrolled out of view. This would save CPU cycles, which may
+ matter for documents with many animations.
+\end{itemize}
+
+\noindent And some items that are more ambitious...
+\begin{itemize}[itemsep=-1pt,leftmargin=*]
+\item Allow figures to be set within a {\tt minipage} (mentioned above).
+\item Double-clicking a figure (or something) could enlarge the figure
+ to give more room for interaction.
+\item Come up with a scheme so that the code that draws a figure could
+ be made part of the document. For certain topics, the code that
+ draws a figure can be as instructive as the figure itself.
+\item Extend the framework somehow so that it can be used within an
+ IDE. Code that's mathematically-oriented is difficult to
+ document within source code using simple text. It would be easier to
+ understand if it's explained as \LaTeX\ output that appears
+ in the source code, rather than in a separate document.
+\item Extend the framework to allow inclusion of snippets of
+ \LaTeX\ output in standard HTML documents. Things like KaTeX and
+ MathJax are convenient, but incomplete relative to \LaTeX.
+\end{itemize}
+
+\newpage
+
+\subsection*{Version History}
+
+\begin{itemize}[itemsep = -3pt]
+\item{0.90} -- July 21, 2022. I've been using this, privately, for
+ several months. Numerous improvements and extensions are possible,
+ but it definitely works.
+\end{itemize}
+
+
+\vskip 0.3cm
+\hrule
+\vskip 0.3cm
+
+
+Thanks to Dan Pratt for insights regarding TypeScript, and
+improvements to the code.
+
+Several people on {\tt tex.stackexchange} very
+patiently answered numerous questions. Thank you.
+
+
+
+\end{document}