summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/grayhints
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/grayhints
Initial commit
Diffstat (limited to 'macros/latex/contrib/grayhints')
-rw-r--r--macros/latex/contrib/grayhints/README.md34
-rw-r--r--macros/latex/contrib/grayhints/doc/grayhints.pdfbin0 -> 92618 bytes
-rw-r--r--macros/latex/contrib/grayhints/doc/grayhints_man.pdfbin0 -> 400042 bytes
-rw-r--r--macros/latex/contrib/grayhints/doc/grayhints_man.tex667
-rw-r--r--macros/latex/contrib/grayhints/examples/gh-eforms.pdfbin0 -> 104160 bytes
-rw-r--r--macros/latex/contrib/grayhints/examples/gh-eforms.tex117
-rw-r--r--macros/latex/contrib/grayhints/examples/gh-fmts-eforms.tex273
-rw-r--r--macros/latex/contrib/grayhints/examples/gh-fmts-hyperref.tex257
-rw-r--r--macros/latex/contrib/grayhints/examples/gh-hyperref.tex151
-rw-r--r--macros/latex/contrib/grayhints/grayhints.dtx570
-rw-r--r--macros/latex/contrib/grayhints/grayhints.ins58
11 files changed, 2127 insertions, 0 deletions
diff --git a/macros/latex/contrib/grayhints/README.md b/macros/latex/contrib/grayhints/README.md
new file mode 100644
index 0000000000..9f65b35c72
--- /dev/null
+++ b/macros/latex/contrib/grayhints/README.md
@@ -0,0 +1,34 @@
+The grayhints Package
+Author: D. P. Story
+Dated: 2018-11-01
+
+This package provides JavaScript code snippets to create 'gray hints'. Gray
+hints, as I term them, are text that appears initially in a text field that
+gives a short hint as to what the contents of the text field should be; for
+example, a text field might contain the hint 'First Name', or a date field
+might read 'yyyy/mm/dd'. As soon as the field comes into focus, the hint
+disappears. It reappears when the field is blurred and the user did not enter
+any text into the field.
+
+What's New (2018/11/01) Revised package to work correctly with PDF-XChange Editor (not
+PDF-XChange View). Improved code for handling the case where the user commits date by
+pressing the Enter key (the data is committed, but the field does not blur). Some commands
+for customizing the user experience in the case of pressing the Enter key to commit.
+
+Dependent packages:
+ (1) eforms (2017/02/27) to use the field fields of eforms.
+ (2) insdljs (2017/03/02) a minimal requirement when using form fields defined
+ by hyperref when calculation fields are used.
+ (3) Hyperref form fields may be used without eforms or insdljs, but the gray
+ hints for calculation fields will not appear.
+
+Package works for dvips/Distiller, pdflatex, lualatex, and xelatex.
+
+PDF Viewers: Adobe Reader DC, PDF-XChange Editor, and, of course Adobe Acrobat.
+
+Enjoy!
+
+Now, I must get back to my retirement.
+
+dps
+dpstory at uakron dot edu
diff --git a/macros/latex/contrib/grayhints/doc/grayhints.pdf b/macros/latex/contrib/grayhints/doc/grayhints.pdf
new file mode 100644
index 0000000000..1fdb414c03
--- /dev/null
+++ b/macros/latex/contrib/grayhints/doc/grayhints.pdf
Binary files differ
diff --git a/macros/latex/contrib/grayhints/doc/grayhints_man.pdf b/macros/latex/contrib/grayhints/doc/grayhints_man.pdf
new file mode 100644
index 0000000000..696bf290bc
--- /dev/null
+++ b/macros/latex/contrib/grayhints/doc/grayhints_man.pdf
Binary files differ
diff --git a/macros/latex/contrib/grayhints/doc/grayhints_man.tex b/macros/latex/contrib/grayhints/doc/grayhints_man.tex
new file mode 100644
index 0000000000..bb180c0dae
--- /dev/null
+++ b/macros/latex/contrib/grayhints/doc/grayhints_man.tex
@@ -0,0 +1,667 @@
+\documentclass{article}
+\usepackage[fleqn]{amsmath}
+\usepackage[
+ web={centertitlepage,designv,forcolorpaper,tight*,latextoc,pro},
+ eforms,aebxmp
+]{aeb_pro}
+\usepackage{grayhints}\previewOff
+\usepackage{graphicx,array,fancyvrb}
+\usepackage{aeb_mlink}
+
+\usepackage{xbmks}
+\DeclareInitView{layoutmag={navitab:UseOutlines}}
+\xbmksetup{colors={int=red},styles={intbf}}
+
+\advance\marginparwidth 8pt
+
+
+%\usepackage{myriadpro}
+%\usepackage{calibri}
+\usepackage[altbullet]{lucidbry}
+
+\def\hardspace{{\fontfamily{cmtt}\selectfont\symbol{32}}}
+\let\uif\textsf
+
+\usepackage{acroman}
+\usepackage[active]{srcltx}
+
+\urlstyle{tt}
+\renewcommand\LayoutTextField[2]{#2}
+
+%\AACalculate{\CalcToGray}
+
+%\def\tutpath{doc/tutorial}
+%\def\tutpathi{tutorial}
+%\def\expath{../examples}
+
+\def\STRUT{\rule{0pt}{14pt}}
+
+
+\DeclareDocInfo
+{
+ university={\AcroTeX.Net},
+ title={The \textsf{grayhints} Package},
+ author={D. P. Story},
+ email={dpstory@acrotex.net},
+ subject=Documentation for the grayhints,
+ talksite={\url{www.acrotex.net}},
+ version={1.2, 2018/26/04},
+ Keywords={LaTeX, form field, hints, AcroTeX},
+ copyrightStatus=True,
+ copyrightNotice={Copyright (C) \the\year, D. P. Story},
+ copyrightInfoURL={http://www.acrotex.net}
+}
+
+\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}}
+
+\chngDocObjectTo{\newDO}{doc}
+\begin{docassembly}
+var titleOfManual="The grayhints Package";
+var manualfilename="Manual_BG_Print_grayhints.pdf";
+var manualtemplate="Manual_BG_Brown.pdf"; // Blue, Green, Brown
+var _pathToBlank="C:/Users/Public/Documents/ManualBGs/"+manualtemplate;
+var doc;
+var buildIt=false;
+if ( buildIt ) {
+ console.println("Creating new " + manualfilename + " file.");
+ doc = \appopenDoc({cPath: _pathToBlank, bHidden: true});
+ var _path=this.path;
+ var pos=_path.lastIndexOf("/");
+ _path=_path.substring(0,pos)+"/"+manualfilename;
+ \docSaveAs\newDO ({ cPath: _path });
+ doc.closeDoc();
+ doc = \appopenDoc({cPath: manualfilename, oDoc:this, bHidden: true});
+ f=doc.getField("ManualTitle");
+ f.value=titleOfManual;
+ doc.flattenPages();
+ \docSaveAs\newDO({ cPath: manualfilename });
+ doc.closeDoc();
+} else {
+ console.println("Using the current "+manualfilename+" file.");
+}
+var _path=this.path;
+var pos=_path.lastIndexOf("/");
+_path=_path.substring(0,pos)+"/"+manualfilename;
+\addWatermarkFromFile({
+ bOnTop:false,
+ bOnPrint:false,
+ cDIPath:_path
+});
+\executeSave();
+\end{docassembly}
+
+
+\begin{document}
+
+\maketitle
+
+\pdfbookmarkx[1]{Title Page}[action={\Named{FirstPage}}]{TitlePage}
+\pdfbookmarkx[1]{Links to AcroTeX.Net}[action={/S/GoTo/D(undefined)},%
+ color=magenta,style={bf}]{acrotex}
+\belowpdfbookmarkx{http://www.acrotex.net}[action={\URI{http://www.acrotex.net}},%
+ color=magenta,style={bf}]{home}
+\belowpdfbookmarkx{http://blog.acrotex.net}[action={\URI{http://blog.acrotex.net}},%
+ color=magenta,style={bf}]{blog}
+
+
+
+\selectColors{linkColor=black}
+\tableofcontents
+\selectColors{linkColor=webgreen}
+
+
+\section{Introduction}
+
+We often see in HTML pages or in compiled executable applications, form
+fields (text fields, input fields) that require user input. The untouched
+field has text within it informing the user of the nature of the data to be
+entered into the field. This ``grayed hint'' immediately disappears
+when the user focuses the cursor on the field.\footnote{Focus on the field by
+clicking inside the form field.} We illustrate the concept with an example or
+two.
+\begin{quote}
+ \textField[\textColor{\matchGray}
+ \TU{Enter your first name so I can get to know you better}
+ \AA{\AAFormat{\FmtToGray{First Name}}
+ \AAKeystroke{\KeyToGray}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ }]{NameFirst1}{2in}{11bp}\vcgBdry[\medskipamount]
+ \textField[\textColor{\matchGray}
+ \TU{Enter your favorite date, in the indicated format}
+ \AA{\AAKeystroke{\DateKeyEx("yyyy/mm/dd");\r\KeyToGray}
+ \AAFormat{\DateFmtEx("yyyy/mm/dd");\r\FmtToGray{yyyy/mm/dd}}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ }]{DateField1}{1in}{11bp}\cgBdry[1.5em]
+ \pushButton[\CA{Reset}
+ \TU{Press to clear to clear all fields.}
+ \A{\JS{this.resetForm();}}]{reset}{}{11bp}
+\end{quote}
+ Of course, the usual tool tips may also be provided.\medskip\noindent
+
+ It is not natural for Adobe form fields to do this, it takes some support
+ code for it to work properly; scripts for the Keystroke, Format, OnFocus,
+ OnBlur, and Calculate events are needed.
+
+The \pkg{grayhints} package works as designed for \app{Adobe Reader} and
+\app{PDF-XChange Editor}.\footnote{\app{PDF-XChange Viewer}, which is no longer
+supported by \href{https://www.tracker-software.com/}{Tracker Software
+Products}, will display the gray hints, but some of the needed JavaScript are not supported.} All {\LaTeX}
+workflows for PDF creation are also supported.
+
+\section{Package options}
+
+Without passing any options, the \pkg{eforms} package of \AEB, dated
+2017/02/27, is required; the document JavaScript function
+\texttt{AllowCalc()} and modified Adobe built-in functions are automatically
+embedded in the document. There are options, however, to modify this default
+setup.
+\begin{description}
+ \item[\texttt{usehyforms}] By default, this package requires
+ \pkg{eforms}, dated 2017/02/27; however, if you are more
+ comfortable using the form fields of \pkg{hyperref}, specify the
+ option \texttt{usehyforms}.\footnote{\pkg{eforms} and
+ \pkg{hyperref} form fields can be used in one document.} When
+ \texttt{usehyforms} is specified, \pkg{insdljs} dated 2017/03/02 or
+ later is required.
+% This requirement is to support the
+% \texttt{usealtadobe}, discussed next.
+ \item[\texttt{nocalcs}] If this option is taken, the document
+ JavaScript function \texttt{AllowCalc()} is not embedded in the document. The
+ implications are that you are not using any calculation fields.
+
+% \item[\texttt{usealtadobe}] If you have the \app{Acrobat} application,
+% you can edit form fields. When you write custom formatting scripts
+% (as does this package) using Adobe's built-in functions, such as
+% \texttt{AFNumber\_Keystroke} and \texttt{AFNumber\_Format}, the
+% user-interface for editing the custom script is not available. The
+% \texttt{usealtadobe} option is passed to \pkg{insldjs};
+% \pkg{insdljs}, in turn, inputs alternate names for the common
+% \app{Adobe} built-ins. Refer to
+% \hyperref[s:altadobfuncs]{Section~\ref*{s:altadobfuncs}} for more
+% information.
+
+ \item[\texttt{nodljs}] When this option is specified, there are no
+ requirements placed on this package; that is, neither \pkg{eforms}
+ nor \pkg{insdljs} are required. Use this option is you are not
+ using any of the Adobe built-in formatting functions.
+\end{description}
+
+\paragraph*{Demo files:} \texttt{gh-eforms.tex,\;gh-hyperref.tex}. The latter file
+uses the \opt{usehyforms} option (and \pkg{hyperref} form fields), while the
+former uses the \pkg{eforms} package. The demo files
+\texttt{gh-fmt-eforms.tex,\;gh-fmt-hyperref.tex} provided additional examples
+of the use of Adobe's built-in formatting functions.
+
+\section{Creating a form field with a gray hint}
+
+In this documentation, we use \pkg{eforms} form fields to illustrate
+concepts, the demonstration file \texttt{gh-hyperref.tex} and
+\texttt{gh-fmt-hyperref.tex} has the form field markup for the case of
+\pkg{hyperref} forms.
+
+There are two cases: (1) an ordinary variable text form field (this includes
+text fields and editable combo boxes) with no calculate script; (2) same as
+(1), but the field has a calculate script.
+
+\subsection{Variable text field, no calculate script}
+
+When there is no calculate script, to obtain a gray hint, it is necessary to
+supply scripts for the Format, Keystroke, OnFocus, and OnBlur events. The
+scripts are all defined in the \pkg{grayhints} package. In addition, the
+color of the text in the text field must be appropriate. We illustrate,
+\begin{Verbatim}[xleftmargin=\parindent,commandchars=!(),numbers=left,numbersep=3bp,fontsize=\small]
+\textField[!color(gray)\TU{Enter your first name so I can get to know you better}
+ \textColor{\matchGray}\AA{%
+ \AAKeystroke{\KeyToGray}
+ \AAFormat{\FmtToGray{First Name}}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray} %!normalfont( required if !app(PDF-XChange Editor) is used)
+}]{NameFirst}{2in}{11bp}
+\end{Verbatim}
+By default, the text color is black and the grayed hint text is light gray.
+The tool tip (\cs{TU}) is grayed out, as it is optional. In line~(2) we match
+the color for the text to the gray color using the command \cs{matchGray} of
+\pkg{grayhints}. Within the argument of \cs{AA}, the \cs{AAFormat},
+\cs{AAKeystroke}, \cs{AAOnFocus}, and \cs{AAOnBlur} scripts are inserted.
+\begin{quote}
+\begin{description}
+ \item{Keystroke Script:} In line~(3), \cs{KeyToGray} is placed within
+ the argument of \cs{AAKeystroke}. This script changes the color
+ of the text to gray when the field is empty.
+ \item{Format Script:} The script snippet \cs{FmtToGray} takes a
+ single argument, which is the text of the hint. In line~(4)
+ the hint is `First Name'.
+ \item{OnFocus Script:} The code snippet \cs{FocusToBlack} is inserted
+ into the argument of \cs{OnFocus}, as seen in line~(5). When the
+ field comes into focus, this script changes the color to the
+ normal color (usually black).
+ \item{OnBlur Script:} In line~(6), the \cs{BlurToBlack} script is
+ placed within the argument of \cs{OnBlur}, in the manner
+ indicated. When the field loses focus (blurred), the script
+ changes the color of text to gray if the field is empty or to
+ its normal color (usually black), otherwise.
+ \item{Calculate Script:} In line~(7), the Calculate event resets the
+ color to gray. This is needed when the user presses the
+ \uif{Enter} key rather than exiting the field by tabbing out, or
+ clicking or tapping an area outside the field. This script is required
+ when (1) there is a possibility that \app{PDF-XChange Editor} is used; or
+ (2) a ``totals'' calculation field.
+\end{description}
+\end{quote}
+The \pkg{hyperref} form field counterpart to the above example is,
+\begin{Verbatim}[xleftmargin=\parindent,commandchars=!(),numbers=left,numbersep=3bp,fontsize=\small]
+\TextField[name={NameFirst},
+ height=11bp,width=2in,charsize=9bp,
+ color={\matchGray},
+ keystroke={\KeyToGray},
+ format={\FmtToGray{First Name}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray} %!normalfont( required if !app(PDF-XChange Editor) is used)
+]{}
+\end{Verbatim}
+The two fields appear side-by-side:
+\begin{quote}
+\textField[\autoCenter{n}\textColor{\matchGray}
+ \TU{Enter your first name so I can get to know you better}
+ \AA{\AAFormat{\FmtToGray{First Name}}
+ \AAKeystroke{\KeyToGray}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+}]{NameFirst2}{2in}{11bp}\cgBdry[0.5em]
+\TextField[name={NameFirst3},
+ height=11bp,width=2in,,charsize=9bp,
+ color=\matchGray,
+ keystroke=\KeyToGray,
+ format=\FmtToGray{First Name},
+ onfocus=\FocusToBlack,
+ onblur=\BlurToBlack]{}\cgBdry[0.5em]
+\pushButton[\CA{Reset}\autoCenter{n}
+ \TU{Press to clear to clear all fields.}
+ \A{\JS{this.resetForm();}}]{reset}{}{11bp}
+\end{quote}
+Both fields appear in their `default' appearance.
+
+
+\subsection{Variable text field, with calculate script}
+
+If you want to make calculations based on entries in other fields, you will need
+the code snippet \cs{CalcToGray} as part of your calculate script.
+\begin{Verbatim}[xleftmargin=\parindent,commandchars={!~@},numbers=left,numbersep=3bp,fontsize=\small]
+\textField[!color~gray@\TU{The total for first and second integers}
+ \textColor{\matchGray}\AA{%
+ \AAKeystroke{AFNumber_Keystroke(0,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{AFNumber_Format(0,1,0,0,"",true);\r\FmtToGray{Total}}
+ \AACalculate{var cArray=new Array("Integer");\r
+ if(AllowCalc(cArray))AFSimple_Calculate("SUM", cArray );\r
+ !textbf~\CalcToGray@}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+}]{TotalNumbers}{1in}{11bp}
+\end{Verbatim}
+The use of \cs{r} is optional, the author uses this to format the script
+within the user-interface of \app{Acrobat} (or \app{PDF-XChange
+Editor}).\footnote{The helper commands \cs{r} and \cs{t} are defined in
+\pkg{eforms}; if \pkg{eforms} is not loaded, use \cs{jsR} and \cs{jsT}
+instead.} The \cs{textColor} (line~(2)), \cs{AAOnFocus} (line~(8)), and
+\cs{AAOnBlur} (line~(9)) are the same as earlier presented. Several comments
+are needed for the \cs{AAKeystroke}, \cs{AAFormat} and \cs{AACalculate}
+lines. The \cs{AACalculate} event above also shows, in general, how to integrate
+the gray hint methodology with other scripts; as a general rule, the gray hints commands
+should come last.
+\begin{itemize}
+ \item This is a number field, so we use the built-in functions
+ \texttt{AFNumber\_Keystroke} and \texttt{AFNumber\_Format} provided
+ by the \app{Adobe Acrobat} and \app{Adobe Acrobat Reader}
+ distributions. In lines~(3) and~(4), the \cs{KeyToGray} and
+ \cs{FmtToGray} code snippets follow the built-ins.\footnote{As a general rule,
+ the code snippets \cs{KeyToGray}, \cs{FmtToGray}, and
+ \cs{CalcToGray} should inserted after any built-in functions.}
+ \item For the Calculate event, special techniques are used. We define
+ an array \texttt{cArray} (line~(5)) consisting of the names of all
+ the dependent fields we use to calculate the value of this field.
+ In line~(6), we make the calculation (\texttt{AFSimple\_Calculate})
+ only if the document JavaScript function \texttt{AllowCalc(cArray)}
+ returns true. The function returns true only if at least one of the
+ fields is not empty. Following the calculation comes the code
+ snippet \cs{CalcToGray}; this changes the text color to gray if the
+ field is empty and to the normal color (usually black) otherwise.
+
+ The function \texttt{AllowCalc()} is defined for all options except
+ for the \opt{nodljs} option.
+\end{itemize}
+Let's go to the examples. Build three fields (four actually), in the first two
+enter integers, the other two fields compute their sum.
+\begin{quote} %\previewOff
+\ding{172}\ \textField[\TU{Enter an integer}
+ \textColor{\matchGray}\AA{%
+ \AAKeystroke{AFNumber_Keystroke(0,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{AFNumber_Format(0,1,0,0,"",true);\r\FmtToGray{First Integer}}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}}
+]{Integer.First}{1in}{11bp}\vcgBdry[3bp]
+\ding{173}\ \textField[\TU{Enter an integer}
+ \textColor{\matchGray}\AA{%
+ \AAKeystroke{AFNumber_Keystroke(0,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{AFNumber_Format(0,1,0,0,"",true);\r\FmtToGray{Second Integer}}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}}
+]{Integer.Second}{1in}{11bp}\vcgBdry[3bp]
+\ding{174}\ \textField[\TU{The total for first and second integers}
+ \textColor{\matchGray}\AA{%
+ \AAKeystroke{AFNumber_Keystroke(0,1,0,0,"",true);\KeyToGray}
+ \AAFormat{AFNumber_Format(0,1,0,0,"",true);\r\FmtToGray{Total}}
+ \AACalculate{var cArray=new Array("Integer");\r
+ if (AllowCalc(cArray)) AFSimple_Calculate("SUM", cArray );\r\CalcToGray}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}}
+]{TotalNumbers}{1in}{11bp}\vcgBdry[3bp]
+\ding{175}\ \textField[\TU{The total for first and second integers}
+ \textColor{\matchGray}\AA{%
+ \AAKeystroke{AFNumber_Keystroke(0,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{AFNumber_Format(0,1,0,0,"",true);\r\FmtToGray{Total}}
+ \AACalculate{var cArray=new Array("Integer");\r
+ AFSimple_Calculate("SUM", cArray );\r\CalcToGray}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}}
+]{TotalNumbers1}{1in}{11bp}\cgBdry[1em]
+\pushButton[\CA{Reset}
+ \TU{Press to clear to clear all fields.}
+ \A{\JS{this.resetForm();}}]{reset}{}{11bp}
+\end{quote}
+Enter numbers into the first two text fields (\ding{172} and \ding{173}), the
+totals of these two fields appear in the last two fields (\ding{174} and
+\ding{175}). Total field \ding{174} uses the recommended script
+\texttt{if(AllowCalc(cArray)} (see line~(6) above), whereas field \ding{175}
+does not. Initially, they both behave the same way until you press the reset
+button. For field \ding{174} the gray hint appears, for field \ding{175} the
+number zero (0) appears. This is because the calculation was allowed to go
+forward, and the calculated value is zero even through none of the dependent
+fields have a value. If you want the gray hint in the total field, you must
+use the conditional \texttt{if(AllowCalc(cArray)}.\footnote{Hence, don't use the \opt{nodljs} option.}
+
+\subsection{Changing the colors for gray hints}
+
+For the fields in which the gray hint scripts are used, there are two colors
+that are relevant, the normal color (defaults to black) and the gray color
+(defaults to light gray). The command
+\cs{normalGrayColors\darg{\ameta{normalcolor}}\darg{\ameta{graycolor}}} sets
+this pair of colors. The arguments for \cs{normalGrayColors} are JavaScript
+colors; they may be in any of the following four forms: (1) a JavaScript
+color array \texttt{["RGB",1,0,0]}; (2) a predefined JavaScript color, such
+as \texttt{color.red}; (3) a declared (or named) {\LaTeX} color such as
+\texttt{red}; or (4) a non-declared {\LaTeX} color such as
+\texttt{[rgb]\darg{1,0,0}}. If the package \pkg{xcolor} is not loaded, only
+methods (1) and (2) are supported.
+
+The package default is
+\cs{normalGrayColors\darg{color.black}\darg{color.ltGray}}. The predefined
+JavaScript colors are,
+\begin{quote}
+% \setlength\tabcolsep{3pt}
+ \setlength{\extrarowheight}{1pt}
+ \begin{tabular}{>{\ttfamily}l>{\ttfamily}l>{\ttfamily}l}
+ \multicolumn{3}{>{\sffamily}c}{Color Models}\\\hline
+ \multicolumn{1}{>{\sffamily}c}{GRAY}&
+ \multicolumn{1}{>{\sffamily}c}{RGB}&
+ \multicolumn{1}{>{\sffamily}c}{CMYK}\\
+ color.black&color.red&color.cyan\\
+ color.white&color.green&color.magenta\\
+ color.dkGray&color.blue\\
+ color.gray\\
+ color.ltGray
+ \end{tabular}
+\end{quote}
+All these colors are defined in the {\LaTeX} color packages, except for possibly \texttt{dkGray},
+\texttt{gray}, and \texttt{ltGray}. These three are defined in \pkg{grayhints}.
+
+We repeat the `First Name' example with different declared colors. We begin by declaring,
+\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small]
+\normalGrayColors{blue}{magenta}
+\end{Verbatim}
+then build a `gray hinted' field,
+\begin{quote}%\previewOff
+ \normalGrayColors{blue}{magenta}%
+ \textField[\textColor{\matchGray}
+ \TU{Enter your first name so I can get to know you better}
+ \AA{\AAFormat{\FmtToGray{First Name}}
+ \AAKeystroke{\KeyToGray}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ }]{NameFirst4}{2in}{11bp}\cgBdry[1em]
+\pushButton[\CA{Reset}
+ \TU{Press to clear to clear all fields.}
+ \A{\JS{this.resetForm();}}]{reset}{}{11bp}
+\end{quote}
+
+\subsection{Remarks on using Adobe built-in formatting functions}\label{s:altadobfuncs}
+
+The \pkg{grayhints} package (as well as does \pkg{insdljs}) offers
+alternating naming of the \app{Adobe} built-in formatting functions. As a
+general rule, all Adobe built-in format, validate, and calculation functions
+that begin with `AF' are given alternate names that begin with `EF'. More
+specifically, \hyperref[table:builtin]{Table~\ref*{table:builtin}} lists the
+Adobe built-in formatting functions and their alternative names. The purpose
+of these alternate names is to allow the JavaScript developer to access the
+scripts through the \app{Acrobat} user-interface.
+\begin{table}[htb]\centering
+\begin{tabular}{>{\ttfamily}l>{\ttfamily}ll}
+\multicolumn{1}{>{\sffamily\bfseries}l}{Adobe function name}&%
+\multicolumn{1}{>{\sffamily\bfseries}l}{Alternate function name}&%
+\multicolumn{1}{>{\sffamily\bfseries}l}{\LaTeX{} command\protect\footnotemark}\\
+AFNumber\_Keystroke&EFNumber\_Keystroke&\cs{NumKey}\\
+AFNumber\_Format&EFNumber\_Format&\cs{NumFmt}\\
+AFPercent\_Keystroke&EFPercent\_Keystroke&\cs{PercentKey}\\
+AFPercent\_Format&EFPercent\_Format&\cs{PercentFmt}\\
+AFDate\_Keystroke&EFDate\_Keystroke&\cs{DateKey}\\
+AFDate\_Format&EFDate\_Format&\cs{DateFmt}\\
+AFDate\_KeystrokeEx&EFDate\_KeystrokeEx&\cs{DateKeyEx}\\
+AFDate\_FormatEx&EFDate\_FormatEx&\cs{DateFmtEx}\\
+AFTime\_Keystroke&EFTime\_Keystroke&\cs{TimeKey}\\
+AFTime\_Format&EFTime\_Format&\cs{TimeFmt}\\
+AFTime\_FormatEx&EFTime\_FormatEx&\cs{TimeFmtEx}\\
+AFSpecial\_Keystroke&EFSpecial\_Keystroke&\cs{SpecialKey}\\
+AFSpecial\_Format&EFSpecial\_Format&\cs{SpecialFmt}\\
+AFSpecial\_KeystrokeEx&EFSpecial\_KeystrokeEx&\cs{SpecialKeyEx}\\
+AFRange\_Validate&EFRange\_Validate&\cs{RangeValidate}\\
+AFSimple\_Calculate&EFSimple\_Calculate&\cs{SimpleCalc}\\
+AFMergeChange&EFMergeChange&\cs{MergeChange}
+\end{tabular}
+\caption{Built-in formatting commands}\label{table:builtin}
+\end{table}
+
+You can learn more about the `AF' versions and their arguments at the
+\href{http://blog.acrotex.net}{Acro\negthinspace\TeX\space Blog} web site; in
+particular, carefully read the article
+\mlurl{http://www.acrotex.net/blog/?p=218}.
+
+\begin{figure}[htb]
+\begin{minipage}[t]{.5\linewidth-2.5pt}\kern0pt\centering
+%\setlength{\fboxsep}{0pt}%
+{\setlength{\fboxsep}{0pt}{\includegraphics[width=\linewidth]{graphics/numFmt-noshowcustom}}}%
+\end{minipage}\hfill
+\begin{minipage}[t]{.5\linewidth-2.5pt}\kern0pt\centering
+{\setlength{\fboxsep}{0pt}{\includegraphics[width=\linewidth]{graphics/numFmt-showcustom}}}%
+\end{minipage}\\[3pt]
+\makebox[.5\linewidth-2.5pt][c]{(a)\ Using \texttt{AFNumber\_Format}}\hfill
+\makebox[.5\linewidth-2.5pt][c]{(b)\ Using \texttt{EFNumber\_Format}}%
+\caption{Format tab: `AF' versus `EF' functions}\label{fig:AltAdbFncs}
+\end{figure}
+
+\leavevmode\hyperref[fig:AltAdbFncs]{Figure~\ref*{fig:AltAdbFncs}} shows the
+impact of using the `EF' functions. On the left, \texttt{AFNumber\_Format} is
+used to format a number field that uses gray hints using the code
+\begin{Verbatim}[xleftmargin=\parindent]
+AFNumber_Format(0,1,0,0,"",true)\r\FmtToGray
+\end{Verbatim}
+As can be seen in sub-figure\,(a), or more accurately not seen, the code is
+not seen through the user-interface of \app{Acrobat}. In sub-figure\,(b) the
+underlying code is seen (and therefore editable through the user-interface)
+because the `EF' version of the function was used:
+\begin{Verbatim}[xleftmargin=\parindent]
+\try{EFNumber_Format(0,1,0,0,"",true)}catch(e){}\r\FmtToGray
+\end{Verbatim}
+Note this code is wrapped in a \texttt{try/catch} construct; this is
+optional. The \pkg{insdljs} package defines a helper command \cs{dlTC} to do the wrapping for you:
+\begin{Verbatim}[xleftmargin=\parindent]
+\dlTC{EFNumber_Format(0,1,0,0,"",true)}\r\FmtToGray
+\end{Verbatim}
+When using \app{pdflatex} or \app{xelatex}, \texttt{try/catch} appears not to
+be needed, but when \app{Adobe Distiller} is used, \app{Acrobat} throws an
+exception when the file is first created. The \texttt{try/\penalty0catch} suppresses
+(catches) the exception.
+
+\footnotetext{These commands are explained in \hyperref[extendGH]{Section~\ref*{extendGH}}}
+
+
+\section{Extending the functionality of \texorpdfstring{\protect\pkg{grayhints}}{grayhints}}\label{extendGH}
+
+The `gray hints' technique works well with fields that require special
+formatting such as the ones provided by built-in formats of \app{Adobe
+Acrobat}, these formats are Number, Percentage, Date, Time, Special, and
+Custom. How `gray hints' functions when one of these special formats is used
+may be acceptable, but if not, we offer an alternative. We begin by
+presenting two date text fields. The one on the left is the default, the one
+on the right is `enhanced.'\footnote{The example that follows is taken from
+\texttt{gh-fmts-forms.tex} where you will find additional
+discussion.}\medbreak
+
+\noindent\hskip-62.5pt\begingroup\advance\linewidth62.5pt
+\begin{minipage}[t]{.5\linewidth-15pt}
+\textField[\textColor{\matchGray}
+ \TU{Enter a date of your choosing}
+ \AA{%
+ \AAOnFocus{\JS{\FocusToBlack}}
+% Using the Adobe Built-in functions directly
+ \AAKeystroke{AFDate_KeystrokeEx("yyyy/mm/dd");\r
+ \KeyToGray}
+ \AAFormat{AFDate_FormatEx("yyyy/mm/dd");\r
+ \FmtToGray{yyyy/mm/dd}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Datefield1}{1in}{11bp}\par\smallskip\noindent
+\begin{Verbatim}[xleftmargin=15pt,fontsize=\footnotesize,commandchars={!~@},numbers=left,numbersep=8pt]
+\textField[\textColor{\matchGray}
+ \TU{Enter a date of your choosing}\AA{%
+ \AAOnFocus{\JS{\FocusToBlack}}
+% !normalfont~Using the Adobe Built-in functions directly@
+ \AAKeystroke{%
+ AFDate_KeystrokeEx("yyyy/mm/dd");\r
+ \KeyToGray}
+ \AAFormat{AFDate_FormatEx("yyyy/mm/dd");\r
+ \FmtToGray{yyyy/mm/dd}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Datefield1}{1in}{11bp}
+\end{Verbatim}
+\footnotesize\makebox[\linewidth][c]{Figure (a): Using Adobe built-in functions}
+\end{minipage}\hfill
+\begin{minipage}[t]{.5\linewidth-15pt}
+\textField[\textColor{\matchGray}
+ \TU{Enter a date of your choosing}\AA{%
+ \AAOnFocus{\JS{\FocusToBlack}}
+% using a customized version of Adobe built-in functions, with LaTeX access
+ \AAKeystroke{\DateKeyEx("yyyy/mm/dd");\r
+ \KeyToGray}
+ \AAFormat{\DateFmtEx("yyyy/mm/dd");\r
+ \FmtToGray{yyyy/mm/dd}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Datefield2}{1in}{11bp}\par\smallskip\noindent
+\begin{Verbatim}[xleftmargin=15pt,fontsize=\footnotesize,commandchars={!~@},numbers=left,numbersep=8pt]
+\textField[\textColor{\matchGray}
+ \TU{Enter a date of your choosing}\AA{%
+ \AAOnFocus{\JS{\FocusToBlack}}
+% !normalfont~Using a customized version of Adobe built-in@
+% !normalfont~functions, with !LaTeX access@
+ \AAKeystroke{!textbf~\DateKeyEx@("yyyy/mm/dd");\r
+ \KeyToGray}
+ \AAFormat{!textbf~\DateFmtEx@("yyyy/mm/dd");\r
+ \FmtToGray{yyyy/mm/dd}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Datefield2}{1in}{11bp}
+\end{Verbatim}
+\setlength{\fboxsep}{0pt}%
+\footnotesize\makebox[\linewidth][c]{Figure~(b): Using \LaTeX{} format commands}
+\end{minipage}
+\endgroup\par\medskip\noindent
+Try entering a bogus date, such as the number `17'. The two fields operate
+identically when you then commit your date by clicking your mouse outside the
+fields. However, the behavior of these two fields differ when you commit your
+bogus date by pressing the \uif{Enter} key. For Figure~(a), the template
+`yyyy/dd/mm' appears in black, whereas, for Figure~(b), the phrase `continue
+editing' appears in black. The latter is the `enhanced' behavior of the
+fields that use the gray hints code.
+
+\paragraph*{Remarks on the {\LaTeX} format commands.} The difference in the two code snippets
+(Figures~(a) and~(b)) is seen in lines~(6) and~(8) of Figure~(b). In these
+two lines we use the special \cs{DateKeyEx} and \cs{DateFmtEx} commands that
+ultimately call the \app{Adobe} built-in functions, but when these special
+commands are used, we can better manage what happens when the \uif{Enter} key
+is pressed. The document author is strongly encouraged to use the {\LaTeX}
+commands in the last column on the right of
+\hyperref[table:builtin]{Table~\ref*{table:builtin}}, instead of using the
+Adobe built-ins, as is done in Figure~(a), or their `EF'
+counterparts.\footnote{Some of these {\LaTeX} commands use the `AF' built-in
+(mostly for the formate events) while others use the `EF' versions of the
+built-ins.}
+
+The \pkg{grayhints} now defines \cs{EnterCommitFailEvent} and
+\cs{CommitSuccessEvent} to customize the user experience when \uif{Enter} key
+is pressed (as opposed to leaving the field by clicking in white space, or
+tabbing away from the field). See the sample files \texttt{gh-fmts-eforms}\marginpar{\small\slshape\raggedleft \texttt{gh-fmts-eforms} referenced}
+for instructions to use these two commands. We present a final example, where the `Enter' events have been changed.\medskip
+
+\EnterCommitFailEvent{\t
+ event.target.strokeColor=color.red;\r\t\t
+ event.target.textColor=color.red;\r\t\t
+ event.value=("weiter bearbeiten");
+% event.value=(event.target.savevalue);
+}
+\CommitSuccessEvent{\t\t
+ event.target.strokeColor=color.black;
+}
+
+%event.value=("weiter bearbeiten");
+
+\noindent
+\textField[\textColor{\matchGray}
+ \TU{Enter a date of your choosing}\AA{%
+ \AAOnFocus{\JS{\FocusToBlack}}
+% using a customized version of Adobe built-in functions, with LaTeX access
+ \AAKeystroke{\DateKeyEx("yyyy/mm/dd");\r
+ \KeyToGray}
+ \AAFormat{\DateFmtEx("yyyy/mm/dd");\r
+ \FmtToGray{yyyy/mm/dd}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Datefield3}{1in}{11bp}\qquad(enter `17' then press enter)\medskip
+
+\EnterCommitFailEvent{}\CommitSuccessEvent{}
+
+\noindent This example appears in the \texttt{gh-fmts-eforms.tex} sample file.
+
+
+\section{My retirement}
+
+Now, I simply must get back to it. \dps
+
+\end{document}
+
+\begin{minipage}{\linewidth-2in-6bp-1em-6pt}\footnotesize
+\textbf{Remark.} The underlying JS function tries hard to make a date from
+the input. You can enter a date in most any format as long it is in the order
+of the date elements YEAR MONTH DAY (yyyy/mm/dd), as determined by the
+formatting template. (For example, try 2018 Jan 10).
+\end{minipage}\medskip
diff --git a/macros/latex/contrib/grayhints/examples/gh-eforms.pdf b/macros/latex/contrib/grayhints/examples/gh-eforms.pdf
new file mode 100644
index 0000000000..f726a7b9f1
--- /dev/null
+++ b/macros/latex/contrib/grayhints/examples/gh-eforms.pdf
Binary files differ
diff --git a/macros/latex/contrib/grayhints/examples/gh-eforms.tex b/macros/latex/contrib/grayhints/examples/gh-eforms.tex
new file mode 100644
index 0000000000..4f9e9f8f5b
--- /dev/null
+++ b/macros/latex/contrib/grayhints/examples/gh-eforms.tex
@@ -0,0 +1,117 @@
+\documentclass{article}
+\usepackage[designiv]{web}
+\usepackage{grayhints}\previewOff
+
+\addtoWebHeight{1in}
+\def\cs#1{\texttt{\char`\\#1}}
+\parindent0pt
+
+%\EnterCommitFailEvent{\jsT\jsT
+% event.target.strokeColor=color.red;\jsR\jsT\jsT
+% event.value=(event.target.savevalue);}
+%\CommitSuccessEvent{event.target.strokeColor=color.black;}
+
+\begin{document}
+
+\begin{center}
+ \large\bfseries Gray Hints
+\end{center}
+The `gray hint' technique requires modifications to the Format,
+Keystroke, OnFocus, OnBlur, and Calculate events.\medskip
+
+\textField[\textColor{\matchGray}
+ \TU{Enter your first name}
+ \AA{\AAFormat{\FmtToGray{First Name}}
+ \AAKeystroke{\KeyToGray}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Name.First}{2in}{11bp}\cgBdry[1em]
+\textField[\textColor{\matchGray}
+ \TU{Enter your last name}
+ \AA{\AAFormat{\FmtToGray{Last Name}}
+ \AAKeystroke{\KeyToGray}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Name.Last}{2in}{11bp}\cgBdry[1em]\vcgBdry[3bp]
+\textField[\textColor{\matchGray}
+ \TU{Enter a date of your choosing}
+ \AA{%
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAKeystroke{\DateKeyEx("yyyy/mm/dd");\r
+ \KeyToGray}
+ \AAFormat{\DateFmtEx("yyyy/mm/dd");\r
+ \FmtToGray{yyyy/mm/dd}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Datefield}{1in}{11bp}\kern2bp\enspace$\Leftarrow$\enspace
+\parbox{\linewidth-1in-2bp-\widthof{\enspace$\Leftarrow$\enspace}}
+{\small Refer to \texttt{gh-fmts-eforms.tex} for additional discussion of
+fields requiring special formatting.}\medskip
+
+The next three fields perform calculations, the last one is the sum of the
+first two. These are fields formatted as numbers. To prevent `Total' field
+from displaying a zero (0) when the dependent fields are empty (and to
+display its gray hint instead), a document JavaScript function was developed,
+named \texttt{AllowCalc(cArray)}. This function returns \texttt{true} if any
+of the fields listed in \texttt{cArray} has a value and returns
+\texttt{false}, otherwise.\vcgBdry[6bp]
+
+\textField[\TU{Enter an integer}
+ \textColor{\matchGray}\AA{%
+ \AAKeystroke{\NumKey(0,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{\NumFmt(0,1,0,0,"",true);\r\FmtToGray{First Integer}}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Integer.First}{1in}{11bp}\vcgBdry[3bp]
+\textField[\TU{Enter an integer}
+ \textColor{\matchGray}\AA{%
+ \AAKeystroke{\NumKey(0,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{\NumFmt(0,1,0,0,"",true);\r\FmtToGray{Second Integer}}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Integer.Second}{1in}{11bp}\vcgBdry[3bp]
+\textField[\TU{The total for first and second integers}
+ \textColor{\matchGray}\AA{%
+ \AAKeystroke{\NumKey(0,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{\NumFmt(0,1,0,0,"",true);\r\FmtToGray{Total}}
+ \AACalculate{var cArray=new Array("Integer");\r
+ if (AllowCalc(cArray))\SimpleCalc("SUM", cArray );\r\CalcToGray}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+}]{TotalNumbers}{1in}{11bp}\medskip
+
+The gray hint technique can apply to editable combo boxes as well.\vcgBdry[3bp]
+\comboBox[\textColor{\matchGray}
+ \TU{Enter or choose your favorite food}\Ff{\FfEdit}
+ \AA{\AAFormat{\FmtToGray{Enter your favorite food}}
+ \AAKeystroke{\KeyToGray}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{combo}{1.65in}{11bp}{(Meat)(Potatoes)(Rice)(Onions)(Pickles)}\cgBdry[1em]
+\pushButton[\CA{Reset}
+ \TU{Press to clear to clear all fields.}
+ \A{\JS{this.resetForm();}}]{reset}{}{11bp}\medskip
+
+The color scheme of the gray hints is changed using
+\cs{normalGrayColors}. The initial value of \cs{textColor}, which sets the
+color of the text, must match, for appearance sake, the choice for the gray
+color; for this reason, the \cs{matchGray} command was developed.\vcgBdry[6bp]
+
+%\normalGrayColors{blue}{magenta}
+\normalGrayColors{color.blue}{color.magenta}
+
+\textField[\textColor{\matchGray}
+ \TU{Enter your favorite pet's name}
+ \AA{\AAFormat{\FmtToGray{Pet's name}}
+ \AAKeystroke{\KeyToGray}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Pet}{1in}{11bp}
+
+\end{document}
diff --git a/macros/latex/contrib/grayhints/examples/gh-fmts-eforms.tex b/macros/latex/contrib/grayhints/examples/gh-fmts-eforms.tex
new file mode 100644
index 0000000000..cf6186da19
--- /dev/null
+++ b/macros/latex/contrib/grayhints/examples/gh-fmts-eforms.tex
@@ -0,0 +1,273 @@
+\documentclass{article}
+\usepackage[designiv]{web}
+\usepackage{grayhints}\previewOff
+\usepackage{fancyvrb}
+
+\addtoWebHeight{1in}
+\def\cs#1{\texttt{\char`\\#1}}
+\let\app\textsf
+\let\pkg\textsf
+\let\uif\textsf
+\parindent0pt
+
+%\EnterCommitFailEvent{\jsT\jsT
+% event.target.strokeColor=color.red;\jsR\jsT\jsT
+% event.value=(event.target.savevalue);}
+%\CommitSuccessEvent{event.target.strokeColor=color.black;}
+
+\begin{document}
+
+\begin{center}
+ \large\bfseries Gray Hints - Formats
+\end{center}
+The `gray hints' technique works well with fields that require special
+formatting such as the ones provided by built-in formats of \app{Adobe
+Acrobat}, these formats are Number, Percentage, Date, Time, Special, and
+Custom. How `gray hints' functions when one of these special formats is
+used may be acceptable, but if not, we offer an alternative. First we compare
+two date fields. The one on the left is the default, the one on the right is
+`enhanced.'\medskip
+
+\textField[\textColor{\matchGray}
+ \TU{Enter a date of your choosing}
+ \AA{%
+ \AAOnFocus{\JS{\FocusToBlack}}
+% Using the Adobe Built-in functions directly
+ \AAKeystroke{AFDate_KeystrokeEx("yyyy/mm/dd");\r
+ \KeyToGray}
+ \AAFormat{AFDate_FormatEx("yyyy/mm/dd");\r
+ \FmtToGray{yyyy/mm/dd}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Datefield1}{1in}{11bp}\kern2bp\quad
+\textField[\textColor{\matchGray}
+ \TU{Enter a date of your choosing}
+ \AA{%
+ \AAOnFocus{\JS{\FocusToBlack}}
+% using a customized version of Adobe built-in functions, with LaTeX access
+ \AAKeystroke{\DateKeyEx("yyyy/mm/dd");\r
+ \KeyToGray}
+ \AAFormat{\DateFmtEx("yyyy/mm/dd");\r
+ \FmtToGray{yyyy/mm/dd}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Datefield2}{1in}{11bp}\hfill\begin{minipage}{\linewidth-2in-6bp-1em-6pt}\footnotesize
+The underlying JS function tries hard to make a date from the input. You can enter a date
+in most any format as long it is in the order of the date elements YEAR MONTH DAY (yyyy/mm/dd), as determined by the
+formatting template. (For example, try 2018 Jan 10).
+\end{minipage}\medskip
+
+
+\textbf{Note:} In the discussion that follows, we assume you are using
+\app{Adobe Acrobat DC} (or prior), \app{Adobe Reader DC} (or prior) or
+\app{PDF-XChange Editor}. These PDF viewers support the JavaScript used
+by this package.\medskip
+
+\textbf{Discussion:} Enter an \emph{invalid date} into each field (such as
+the number 17), and \emph{commit} that number to the field. There are several
+ways of committing form data: (1) press the \uif{Enter} key; (2) tab out of the
+field; (3) click or tap outside the field; and (4) move to another
+page.\footnote{Apparently, \app{PDF-XChange Editor} does not commit field
+data when the page is turned, unlike the Adobe PDF viewer.} The behavior of
+the field is the same for cases (2)--(4); in those cases, the field loses
+focus (or is blurred). In the first case, the data is committed, but
+\emph{not blurred}. This latter case is a bit of a problem because the blur
+event has JavaScript that sets the field text color, as appropriate.\medskip
+
+In the above two fields, enter the number 17 (or any invalid date) and commit
+the data using method (2) or (3); now repeat the exercise for the two fields,
+but commit using method (1). Do you notice a difference?\medskip
+
+\textbf{Discussion of (2) and (3):} This is the usual case; after the alert
+dialog box is dismissed, the fields are grayed out again. That's the effect
+desired by this package.\medskip
+
+\textbf{Discussion of (1):} When the data is committed by pressing the
+\uif{Enter} key and the alert box is dismissed, for the field on the left
+`yyyy/mm/dd' appears in black, whereas, for the field on the right, the
+string `continue editing' appears in black. In each case, you can click
+within the field and continue editing the date. Use methods (2) or (3) to
+commit your final response. Of the two fields, the behavior of the field on
+the right is the preferred one.\medskip
+
+The behavior of the field on the right requires some special code.
+\begin{Verbatim}[xleftmargin=15pt,fontsize=\small,numbers=left,numbersep=9pt,commandchars={!~@}]
+\textField[\textColor{\matchGray}
+ \TU{Enter a date of your choosing}
+ \AA{%
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAKeystroke{\DateKeyEx("yyyy/mm/dd");\r
+ \KeyToGray}
+ \AAFormat{\DateFmtEx("yyyy/mm/dd");\r
+ \FmtToGray{yyyy/mm/dd}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray} % <-!normalfont~ required for !app~PDF-XChange Editor@@
+}]{Datefield2}{1in}{11bp}
+\end{Verbatim}
+The code above is identical to that of the left-hand field with two
+exceptions, marked above by (5) and~(7). On these lines, the commands
+\cs{DateKeyEx} and \cs{DateFmtEx} are used (instead of the Adobe built-in
+functions directly). When these two are inserted, then we get the behavior of
+the field on the right on page 1.\medskip
+
+
+
+When the changes shown in lines~(5) and~(7) are made, you can customize the
+behavior of the field when the date is committed by pressing the \uif{Enter}
+key.\medskip
+
+\EnterCommitFailEvent{event.value=("weiter bearbeiten");}
+\textField[\textColor{\matchGray}
+ \TU{Enter a date of your choosing}
+ \AA{%
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAKeystroke{\DateKeyEx("yyyy/mm/dd");\r
+ \KeyToGray}
+ \AAFormat{\DateFmtEx("yyyy/mm/dd");\r
+ \FmtToGray{yyyy/mm/dd}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Datefield3}{1in}{11bp}\medskip
+
+Here, we use \cs{EnterCommitFailEvent} and declare,
+\begin{Verbatim}[xleftmargin=15pt,fontsize=\small]
+\EnterCommitFailEvent{event.value=("weiter bearbeiten");}
+\end{Verbatim}
+which changes the text string that appears when \uif{Enter} is pressed for an invalid date.\medskip
+
+\EnterCommitFailEvent{%
+ event.target.strokeColor=color.red;
+ event.value=(event.target.savevalue);}
+\CommitSuccessEvent{event.target.strokeColor=color.black;}
+We can get a different effect with
+\begin{Verbatim}[xleftmargin=15pt,fontsize=\small]
+\EnterCommitFailEvent{%
+ event.target.strokeColor=color.red;
+ event.value=(event.target.savevalue);}
+\CommitSuccessEvent{event.target.strokeColor=color.black;}
+\end{Verbatim}
+The action declared by \cs{EnterCommitFailEvent} is to change the border
+color to red, and secondly, to set the value of the field to the saved value
+(\texttt{event.target.savevalue}). The property \texttt{savevalue} is defined
+through the use of the special commands \cs{DateKeyEx} and \cs{DateFmtEx}.
+The action of \cs{CommitSuccessEvent} returns the fields border color to
+black.\medskip
+
+\textField[\textColor{\matchGray}
+ \TU{Enter a date of your choosing}
+ \AA{%
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAKeystroke{\DateKeyEx("yyyy/mm/dd");\r
+ \KeyToGray}
+ \AAFormat{\DateFmtEx("yyyy/mm/dd");\r
+ \FmtToGray{yyyy/mm/dd}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Datefield4}{1in}{11bp}\medskip
+
+Now, when an invalid date is entered using the \uif{Enter} key, the border
+color of the field is changed to red to indicate to the user that the date
+in invalid and needs to be modified. Tabbing or clicking outside the field, as
+usual, blurs the field; any invalid date is removed and the grayed hint
+appears.\medskip
+
+To return to the default declarations, expand \verb!\EnterCommitFailEvent{}! and
+\verb!\CommitSuccessEvent{}!. The underlying default actions are,
+\begin{Verbatim}[xleftmargin=15pt,fontsize=\small]
+\newcommand\FailStringDef{continue editing}
+\newcommand\EnterCommitFailDef{event.value=("\FailStringDef");}
+\end{Verbatim}
+A localization of language can be performed by redefining
+\cs{FailStringDef}
+\begin{Verbatim}[xleftmargin=15pt,fontsize=\small]
+\renewcommand\FailStringDef{weiter bearbeiten}
+\end{Verbatim}
+
+The next example changes the border, the text color, and the error message.\medskip
+
+\EnterCommitFailEvent{\t
+ event.target.strokeColor=color.red;\r\t\t
+ event.target.textColor=color.red;\r\t\t
+ event.value=("needs editing");
+}
+\CommitSuccessEvent{\t\t
+ event.target.strokeColor=color.black;
+}
+
+\noindent
+\textField[\textColor{\matchGray}
+ \TU{Enter a date of your choosing}\AA{%
+ \AAOnFocus{\JS{\FocusToBlack}}
+% using a customized version of Adobe built-in functions, with LaTeX access
+ \AAKeystroke{\DateKeyEx("yyyy/mm/dd");\r
+ \KeyToGray}
+ \AAFormat{\DateFmtEx("yyyy/mm/dd");\r
+ \FmtToGray{yyyy/mm/dd}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Datefield5}{1in}{11bp}\qquad(enter `17' then press enter)\medskip
+
+This same scheme should work for all the built-in Acrobat formats, let's look
+at the number format.\medskip
+
+\EnterCommitFailEvent{}\CommitSuccessEvent{}
+\textField[\TU{Enter an integer}
+ \textColor{\matchGray}\AA{%
+ \AAKeystroke{\NumKey(0,1,0,0,"",true);\r\KeyToGray}
+ \AAFormat{\NumFmt(0,1,0,0,"",true);\r
+ \FmtToGray{Enter an Integer}}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Integer}{1in}{11bp}\medskip
+
+\textbf{Creating a Percent text field.}\medskip
+
+\textField[\textColor{\matchGray}\AA{%
+ \AAKeystroke{\PercentKey(2,1);\r
+ \KeyToGray}
+ \AAFormat{\PercentFmt(2,1);\r
+ \FmtToGray{Enter a number}}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Percent}{2in}{11bp} (don't enter the percent symbol \%)\medskip
+
+\textbf{Creating a Phone Number text field.}\medskip
+
+Enter a phone number: \textField[\textColor{\matchGray}\AA{%
+ \AAKeystroke{\SpecialKey(2);\r
+ \KeyToGray}
+ \AAFormat{\SpecialFmt(2);\r
+ \FmtToGray{(123) 456-7890}}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Phone}{2in}{11bp}\medskip
+
+The underlying JS function tries hard to make a phone number out of the input. The phone number can
+be entered in any recognized format; even something like 1234567890 is formatted.\medbreak
+
+\textbf{Creating a Custom time format text field.}\medskip
+
+\def\parentt{(tt)} % necessary to insert within arg of \TimeFmtEx
+\textField[\textColor{\matchGray}\AA{%
+ \AAKeystroke{\TimeKey(0);\r
+ \KeyToGray}
+ \AAFormat{\TimeFmtEx("h:MM \parentt");\r
+ \FmtToGray{Enter a time}}
+ \AAOnFocus{\JS{\FocusToBlack}}
+ \AAOnBlur{\JS{\BlurToBlack}}
+ \AACalculate{\CalcToGray}
+}]{Time}{2in}{11bp}\kern1bp\pushButton[\TU{Push to Use Current Time}
+\CA{UCT}\A{\JS{%
+ var cTime=util.printd("h:MM",new Date());\r
+ var f=this.getField("Time");\r
+ f.value=cTime;
+}}]{pbTime}{}{11bp}\medskip
+
+Detailed information on formatting with the built-in functions of \app{Acrobat} may be found at
+the \href{http://blog.acrotex.net}{Acro\negthinspace\TeX\space Blog}; in particular, see the article
+\url{http://www.acrotex.net/blog/?p=218}.
+
+\end{document}
diff --git a/macros/latex/contrib/grayhints/examples/gh-fmts-hyperref.tex b/macros/latex/contrib/grayhints/examples/gh-fmts-hyperref.tex
new file mode 100644
index 0000000000..ea8f2337ac
--- /dev/null
+++ b/macros/latex/contrib/grayhints/examples/gh-fmts-hyperref.tex
@@ -0,0 +1,257 @@
+\documentclass{article}
+\usepackage[designiv]{web}
+\usepackage[usehyforms]{grayhints}
+\usepackage{fancyvrb}
+
+
+\addtoWebHeight{1in}
+\def\cs#1{\texttt{\char`\\#1}}
+\let\app\textsf
+\let\pkg\textsf
+\let\uif\textsf
+\parindent0pt
+
+%\EnterCommitFailEvent{\jsT\jsT
+% event.target.strokeColor=color.blue;\jsR\jsT\jsT
+% event.value=(event.target.savevalue);}
+%\CommitSuccessEvent{event.target.strokeColor=color.red;}
+
+
+\begin{document}
+\begin{Form}
+\begin{center}\large\bfseries Gray Hints - Formats
+\end{center}
+The `gray hint' technique requires modifications to the Format,
+Keystroke, OnFocus, OnBlur, and Calculate events. Refer to \texttt{gh-fmts-eforms} for a more
+discussion of these fields.\medskip
+
+\renewcommand\LayoutTextField[2]{#2}
+\renewcommand\LayoutChoiceField[2]{#2}
+
+\TextField[%
+ name={Datefield1},
+ height=11bp,
+ width=1in,
+ color={\matchGray},
+ keystroke={AFDate_KeystrokeEx("yyyy/mm/dd");\jsR
+ \KeyToGray},
+ format={AFDate_FormatEx("yyyy/mm/dd");\jsR
+ \FmtToGray{yyyy/mm/dd}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray}
+]{}\kern2bp\quad
+\TextField[%
+ name={Datefield2},
+ height=11bp,
+ width=1in,
+ color={\matchGray},
+ keystroke={\DateKeyEx("yyyy/mm/dd");\jsR
+ \KeyToGray},
+ format={\DateFmtEx("yyyy/mm/dd");\jsR
+ \FmtToGray{yyyy/mm/dd}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray}
+]{}\medskip
+
+\textbf{Note:} In the discussion that follows, we assume you are using
+\app{Adobe Acrobat DC} (or prior), \app{Adobe Reader DC} (or prior) or
+\app{PDF-XChange Editor}. These PDF viewers support the JavaScript used
+by this package.\medskip
+
+The behavior of the field on the right requires some special code.
+\begin{Verbatim}[xleftmargin=15pt,fontsize=\small,numbers=left,numbersep=9pt,commandchars={!~@}]
+\TextField[%
+ name={Datefield2},
+ height=11bp,width=1in,charsize=9bp,
+ color={\matchGray},
+ keystroke={\DateKeyEx("yyyy/mm/dd");\jsR
+ \KeyToGray},
+ format={\DateFmtEx("yyyy/mm/dd");\jsR
+ \FmtToGray{yyyy/mm/dd}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray} % <-!normalfont~ required for !app~PDF-XChange Editor@@
+]{}\end{Verbatim}
+The code above is identical to that of the left-hand field with two
+exceptions, marked above by (5) and~(7). On these lines, the commands
+\cs{DateKeyEx} and \cs{DateFmtEx} are used (instead of the Adobe built-in
+functions directly). When these two are inserted, then we get the behavior of
+the field on the right on page 1.\medskip
+
+When the changes shown in lines~(5) and~(7) are made, you can customize the
+behavior of the field when the date is committed by pressing the \uif{Enter}
+key.\medskip
+
+\EnterCommitFailEvent{event.value=("weiter bearbeiten");}
+\TextField[%
+ name={Datefield3},
+ height=11bp,width=1in,charsize=9bp,
+ color={\matchGray},
+ keystroke={\DateKeyEx("yyyy/mm/dd");\jsR
+ \KeyToGray},
+ format={\DateFmtEx("yyyy/mm/dd");\jsR
+ \FmtToGray{yyyy/mm/dd}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray}
+]{}\medskip
+
+Here, we use \cs{EnterCommitFailEvent} and declare,
+\begin{Verbatim}[xleftmargin=15pt,fontsize=\small]
+\EnterCommitFailEvent{event.value=("weiter bearbeiten");}
+\end{Verbatim}
+which changes the text string that appears when \uif{Enter} is pressed for an invalid date.\medskip
+
+\EnterCommitFailEvent{%
+ event.target.strokeColor=color.blue;
+ event.value=(event.target.savevalue);}
+\CommitSuccessEvent{event.target.strokeColor=color.red;}
+We can get a different effect with
+\begin{Verbatim}[xleftmargin=15pt,fontsize=\small]
+\EnterCommitFailEvent{%
+ event.target.strokeColor=color.blue;
+ event.value=(event.target.savevalue);}
+\CommitSuccessEvent{event.target.strokeColor=color.black;}
+\end{Verbatim}
+The action declared by \cs{EnterCommitFailEvent} is to change the border
+color to blue, and secondly, to set the value of the field to the saved value
+(\texttt{event.target.savevalue}). The property \texttt{savevalue} is defined
+through the use of the special commands \cs{DateKeyEx} and \cs{DateFmtEx}.
+The action of \cs{CommitSuccessEvent} returns the fields border color to
+black.\medskip
+
+\TextField[%
+ name={Datefield4},
+ height=11bp,width=1in,charsize=9bp,
+ color={\matchGray},
+ keystroke={\DateKeyEx("yyyy/mm/dd");\jsR
+ \KeyToGray},
+ format={\DateFmtEx("yyyy/mm/dd");\jsR
+ \FmtToGray{yyyy/mm/dd}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray}
+]{}\medskip
+
+Now, when an invalid date is entered using the \uif{Enter} key, the border
+color of the field is changed to blue to indicate to the user that the date
+in invalid and needs to be modified. Tabbing or clicking outside the field, as
+usual, blurs the field; any invalid date is removed and the grayed hint
+appears.\medskip
+
+To return to the default declarations, expand \verb!\EnterCommitFailEvent{}! and
+\verb!\CommitSuccessEvent{}!. The underlying default actions are,
+\begin{Verbatim}[xleftmargin=15pt,fontsize=\small]
+\newcommand\FailStringDef{continue editing}
+\newcommand\EnterCommitFailDef{event.value=("\FailStringDef");}
+\end{Verbatim}
+A localization of language can be performed by redefining
+\cs{FailStringDef}
+\begin{Verbatim}[xleftmargin=15pt,fontsize=\small]
+\renewcommand\FailStringDef{weiter bearbeiten}
+\end{Verbatim}
+
+The next example changes the border, the text color, and the error message.\medskip
+
+\EnterCommitFailEvent{\jsT
+ event.target.strokeColor=color.blue;\jsR\jsT\jsT
+ event.target.textColor=color.blue;\jsR\jsT\jsT
+ event.value=("needs editing");
+}
+\CommitSuccessEvent{\jsT\jsT
+ event.target.strokeColor=color.red;
+}
+
+\noindent
+\TextField[%
+ name={Datefield5},
+ height=11bp,width=1in,charsize=9bp,
+ color={\matchGray},
+ keystroke={\DateKeyEx("yyyy/mm/dd");\jsR
+ \KeyToGray},
+ format={\DateFmtEx("yyyy/mm/dd");\jsR
+ \FmtToGray{yyyy/mm/dd}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray}
+]{}\qquad(enter `17' then press enter)\medskip
+
+
+
+This same scheme should work for all the built-in Acrobat formats, let's look
+at the number format.\medskip
+
+\EnterCommitFailEvent{}\CommitSuccessEvent{}
+\TextField[%
+ name=Integer,
+ height=11bp,width=1in,charsize=9bp,
+ color={\matchGray},
+ keystroke={\NumKey(0,1,0,0,"",true);\jsR\KeyToGray},
+ format={\NumFmt(0,1,0,0,"",true);\jsR
+ \FmtToGray{Enter an Integer}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray}
+]{}\smallskip
+
+\textbf{Creating a Percent text field.}\medskip
+
+\TextField[%
+ name=Percent,
+ height=11bp,width=2in,charsize=9bp,
+ color=\matchGray,
+ keystroke={\PercentKey(2,1);\jsR
+ \KeyToGray},
+ format={\PercentFmt(2,1);\jsR
+ \FmtToGray{Enter a number}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray}
+]{} (don't enter the percent symbol \%)\medskip
+
+\textbf{Creating a Phone Number text field.}\medskip
+
+Enter a phone number: \TextField[%
+ name=Phone,
+ height=11bp,width=2in,charsize=9bp,
+ color=\matchGray,
+ keystroke={\SpecialKey(2);\jsR
+ \KeyToGray},
+ format={\SpecialFmt(2);\jsR
+ \FmtToGray{(123) 456-7890}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray}
+]{}\medskip
+
+The underlying JS function tries hard to make a phone number out of the input. The phone number can
+be entered in any recognized format; even something like 1234567890 is recognized and formatted.\medbreak
+
+\textbf{Creating a Custom time format text field.}\medskip
+
+\def\parentt{(tt)} % necessary to insert within arg of \TimeFmtEx
+\TextField[%
+ name=Time,
+ height=11bp,width=2in,charsize=9bp,
+ color=\matchGray,
+ keystroke={\TimeKey(0);\jsR
+ \KeyToGray},
+ format={\TimeFmtEx("h:MM \parentt");\jsR
+ \FmtToGray{Enter a time}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray}
+]{}\quad\PushButton[%
+ height=11bp,
+ name=pbtime,
+ onclick={var cTime=util.printd("h:MM",new Date());\jsR
+ var f=this.getField("Time");\jsR
+ f.value=cTime;}]{UCT}\medskip
+
+Detailed information on formatting with the built-in functions of \app{Acrobat} may be found at
+the \href{http://blog.acrotex.net}{Acro\negthinspace\TeX\space Blog}; in particular, see the article \url{http://www.acrotex.net/blog/?p=218}.
+
+\end{Form}
+\end{document}
diff --git a/macros/latex/contrib/grayhints/examples/gh-hyperref.tex b/macros/latex/contrib/grayhints/examples/gh-hyperref.tex
new file mode 100644
index 0000000000..862b9d30dc
--- /dev/null
+++ b/macros/latex/contrib/grayhints/examples/gh-hyperref.tex
@@ -0,0 +1,151 @@
+\documentclass{article}
+\usepackage[designiv]{web}
+\usepackage[usehyforms]{grayhints}
+
+\addtoWebHeight{1in}
+\def\cs#1{\texttt{\char`\\#1}}
+\parindent0pt
+
+%\EnterCommitFailEvent{\jsT\jsT
+% event.target.strokeColor=color.blue;\jsR\jsT\jsT
+% event.value=(event.target.savevalue);}
+%\CommitSuccessEvent{event.target.strokeColor=color.red;}
+
+
+\begin{document}
+\begin{Form}
+\begin{center}\large\bfseries Gray Hints
+\end{center}
+The `gray hint' technique requires modifications to the Format,
+Keystroke, OnFocus, OnBlur, and Calculate events.\medskip
+
+\renewcommand\LayoutTextField[2]{\mbox{#2}}
+\renewcommand\LayoutChoiceField[2]{\mbox{#2}}
+
+\TextField[%
+ name={Name.First},
+ height=11bp,
+ width=2in,
+ color={\matchGray},
+ keystroke=\KeyToGray,
+ format={\FmtToGray{First Name}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray}
+]{First Name:}\quad
+\TextField[%
+ name={Name.Laat},
+ height=11bp,
+ width=2in,
+ color={\matchGray},
+ keystroke=\KeyToGray,
+ format={\FmtToGray{Last Name}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray}
+]{}\medskip
+
+\TextField[%
+ name=Datefield,
+ height=11bp,
+ width=1in,
+ color={\matchGray},
+ keystroke={\DateKeyEx("yyyy/mm/dd");\jsR\KeyToGray},
+ format={\DateFmtEx("yyyy/mm/dd");\jsR\FmtToGray{yyyy/mm/dd}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray}
+]{}\enspace$\Leftarrow$\enspace
+\parbox{\linewidth-1in-\widthof{\enspace$\Leftarrow$\enspace}}
+{\small Refer to \texttt{gh-fmts-hyperref.tex} for additional discussion of
+fields requiring special formatting.}\medskip
+
+The next three fields perform calculations, the last one is the sum of the
+first two. These are fields formatted as numbers. To prevent `Total' field
+from displaying a zero (0) when the dependent fields are empty (and to
+display its gray hint instead), a document JavaScript function was developed,
+named \texttt{AllowCalc(cArray)}. This function returns \texttt{true} if any
+of the fields listed in \texttt{cArray} has a value and returns
+\texttt{false}, otherwise.\smallskip
+
+\TextField[%
+ name=Integer.First,
+ height=11bp,
+ width=1in,
+ color={\matchGray},
+ keystroke={\NumKey(0,1,0,0,"",true);\KeyToGray},
+ format={\NumFmt(0,1,0,0,"",true); \FmtToGray{First Integer}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray}
+]{}\smallskip
+
+\TextField[%
+ name=Integer.Second,
+ height=11bp,
+ width=1in,
+ color={\matchGray},
+ keystroke={\NumKey(0,1,0,0,"",true); \KeyToGray},
+ format={\NumFmt(0,1,0,0,"",true); \FmtToGray{Second Integer}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray}
+]{}\smallskip
+
+% The use of \jsR (\jsT) is for editing purposes, should you have Acrobat or PDF-XChange Pro; otherwise, they are optional
+\TextField[%
+ name=TotalNumber,
+ height=11bp,
+ width=1in,
+ color={\matchGray},
+ keystroke={\NumKey(0,1,0,0,"",true);\jsR\KeyToGray},
+ format={\NumFmt(0,1,0,0,"",true);\jsR\FmtToGray{Total}},
+ calculate={var cArray=new Array("Integer");\jsR
+ if (AllowCalc(cArray))\SimpleCalc("SUM", cArray );\jsR\CalcToGray},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack}
+]{}\medskip
+
+The gray hint technique can apply to editable combo boxes as well.\smallskip
+
+\ChoiceMenu[%
+ name=combo,
+ combo,
+ width=1.65in,
+ height=11bp,
+ edit,
+ color={\matchGray},
+ keystroke={\KeyToGray},
+ format={\FmtToGray{Enter your favorite food}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray}
+]{}{Meat,Potatoes,Rice,Onions,Pickles}\medskip
+
+The color scheme of the gray hints can be changed using
+\cs{normalGrayColors}. The initial value of \cs{textColor}, which sets the
+color of the text, must match, for appearance sake, the choice for the gray
+color; for this reason, the \cs{matchGray} command was developed.\smallskip
+
+
+\normalGrayColors{color.blue}{color.magenta}
+
+\TextField[%
+ name=Pet,
+ width=1in,
+ height=11bp,
+ color={\matchGray},
+ keystroke={\KeyToGray},
+ format={\FmtToGray{Pet's name}},
+ onfocus={\FocusToBlack},
+ onblur={\BlurToBlack},
+ calculate={\CalcToGray}
+]{Pet}\medskip
+
+\PushButton[%
+ height=11bp,
+ name=reset,
+ onclick={this.resetForm();}]{Reset}
+
+\end{Form}
+\end{document}
diff --git a/macros/latex/contrib/grayhints/grayhints.dtx b/macros/latex/contrib/grayhints/grayhints.dtx
new file mode 100644
index 0000000000..b0b06cbc11
--- /dev/null
+++ b/macros/latex/contrib/grayhints/grayhints.dtx
@@ -0,0 +1,570 @@
+%\iffalse
+% makeindex -s gglo.ist -o grayhints.gls grayhints.glo
+% makeindex -s gind.ist -o grayhints.ind grayhints.idx
+%<*copyright>
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% grayhints.sty package, %%
+%% Copyright (C) 2017--2018 %%
+%% dpstory@uakron.edu %%
+%% %%
+%% This program can redistributed and/or modified under %%
+%% the terms of the LaTeX Project Public License %%
+%% Distributed from CTAN archives in directory %%
+%% macros/latex/base/lppl.txt; either version 1.2 of the %%
+%% License, or (at your option) any later version. %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%</copyright>
+%<package>\NeedsTeXFormat{LaTeX2e}[1997/12/01]
+%<package>\ProvidesPackage{grayhints}
+%<package> [2018/11/01 v1.2 grayhints: Create gray hints in text fields]
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{xcolor}
+\usepackage[colorlinks,hyperindex=false]{hyperref}
+\usepackage{grayhints}
+%\pdfstringdefDisableCommands{\let\\\textbackslash}
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\gdef\brpr#1{\texttt{\char123\relax#1\char125\relax}}
+\let\darg\brpr
+\let\env\texttt
+\let\opt\texttt
+\let\app\textsf
+\let\pkg\textsf
+\def\visispace{\symbol{32}}
+\def\ameta#1{\ensuremath{\langle\textit{\texttt{#1}}\rangle}}
+\def\meta#1{\textsl{\texttt{#1}}}
+\def\SUB#1{\ensuremath{{}_{\mbox{\scriptsize\ttfamily#1}}}}
+%\def\cs#1{\texttt{\bslash#1}}
+\DeclareRobustCommand{\tmspace}[3]{%
+ \ifmmode\mskip#1#2\else\kern#1#3\fi\relax}
+\renewcommand{\,}{\tmspace+\thinmuskip{.1667em}}
+\let\thinspace\,
+\renewcommand{\!}{\tmspace-\thinmuskip{.1667em}}
+\let\negthinspace\!
+\renewcommand{\:}{\tmspace+\medmuskip{.2222em}}
+\let\medspace\:
+\newcommand{\negmedspace}{\tmspace-\medmuskip{.2222em}}
+\renewcommand{\;}{\tmspace+\thickmuskip{.2777em}}
+\let\thickspace\;
+\newcommand{\negthickspace}{\tmspace-\thickmuskip{.2777em}}
+\makeatletter
+\renewcommand{\paragraph}
+ {\@startsection{paragraph}{4}{0pt}{6pt}{-3pt}
+ {\normalfont\normalsize\bfseries}}
+\renewenvironment{quote}[1][]
+ {\def\@rgi{#1}\ifx\@rgi\@empty
+ \let\rghtm\@empty\else\def\rghtm{\rightmargin\leftmargin}\fi
+ \list{}{\rghtm} %{\rightmargin\leftmargin}%
+ \item\relax}
+ {\endlist}
+\makeatother
+\InputIfFileExists{aebdocfmt.def}{\PackageInfo{grayhints}{Inputting aebdocfmt.def}}
+ {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax
+ \PackageInfo{grayhints}{aebdocfmt.def cannot be found}}
+\begin{document}
+\def\CMD#1{\textbackslash#1}
+ \GetFileInfo{grayhints.sty}
+ \title{\textsf{grayhints}: Create gray hints in text fields}
+ \author{D. P. Story\\
+ Email: \texttt{dpstory@acrotex.net}}
+ \date{processed \today}
+ \maketitle
+ \tableofcontents
+ \let\Email\texttt
+ \DocInput{grayhints.dtx}
+\IfFileExists{\jobname.ind}{\newpage\setupFullwidth\par\PrintIndex}{\paragraph*{Index} The index goes here.\\Execute
+ \texttt{makeindex -s gind.ist -o grayhints.ind grayhints.idx}\\on the command line and recompile
+ \texttt{grayhints.dtx}.}
+\IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of changes goes here.\\Execute
+ \texttt{makeindex -s gglo.ist -o grayhints.gls grayhints.glo}\\on the command line and recompile
+ \texttt{grayhints.dtx}.}
+\end{document}
+%</driver>
+% \fi
+% \MakeShortVerb{|}
+%
+% \InputIfFileExists{aebdonotindex.def}{\PackageInfo{web}{Inputting aebdonotindex.def}}
+% {\PackageInfo{web}{cannot find aebdonotindex.def}}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+% \changes{v1.2}{2018/11/01}{Revisions to support PDF-XChange Editor}
+% \changes{v1.1}{2018/10/04}{Modify \string\cs{FmtToGray}, \string\cs{FocusToBlack}, and
+% \string\cs{BlurToBlack} for better behavior when entry is left empty}
+% \section{Description}\previewOff
+% We often see in HTML pages or compiled executable applications, form fields (text fields, input fields)
+% that require user input. The untouched field has text within it that informs the user
+% of the nature of the data to be entered into the field. This `grayed hint' immediately
+% disappears when the user focuses the cursor on the field. Lest I be accused of being too obtuse, we
+% illustrate with an example or two.
+%\begin{quote}\small
+%\def\myDateFmt{yyyy/mm/dd}
+% \textField[\textColor{\matchGray}
+% \TU{Enter your first name so I can get to know you better}
+% \AA{\AAFormat{\FmtToGray{First Name}}
+% \AAKeystroke{\KeyToGray}
+% \AAOnFocus{\JS{\FocusToBlack}}
+% \AAOnBlur{\JS{\BlurToBlack}}
+% \AACalculate{\CalcToGray}
+% }]{NameFirst}{2in}{11bp}\vcgBdry[\medskipamount]
+% \textField[\textColor{\matchGray}
+% \TU{Enter your favorite date, in the indicated format}
+% \AA{\AAKeystroke{\DateKeyEx("\myDateFmt");\KeyToGray}
+% \AAFormat{\DateFmtEx("\myDateFmt");\jsR\FmtToGray{\myDateFmt}}
+% \AAOnFocus{\JS{\FocusToBlack}}
+% \AAOnBlur{\JS{\BlurToBlack}}
+% \AACalculate{\CalcToGray}
+% }]{DateField}{1in}{11bp}\cgBdry[1.5em]
+% \pushButton[\CA{Reset}
+% \TU{Press to clear to clear all fields.}
+% \A{\JS{this.resetForm();}}]{reset}{}{11bp}
+%\end{quote}
+% Of course, the usual tool tips may also be provided.\medskip
+%
+% \noindent It is not natural for Adobe form fields to do this, it takes a lot of support code for
+% it to work properly; the Keystroke, Format, OnFocus, OnBlur, and Calculate events are needed. The
+% verbatim listing of the first example field above is,
+%
+%\begin{quote}\small
+%|\textField[\textColor{\matchGray}|\\
+%| \TU{Enter your first name so I can get to know you better}|\\
+%| \AA{\AAFormat{\FmtToGray{First Name}}|\\
+%| \AAKeystroke{\KeyToGray}|\\
+%| \AAOnFocus{\JS{\FocusToBlack}}|\\
+%| \AAOnBlur{\JS{\BlurToBlack}}|\\
+%| \AACalculate{\CalcToGray} %<-| required if using PDF-XChange Editor\\
+%|}]{NameFirst}{2in}{11bp}|
+%\end{quote}
+% Code snippets are inserted into the Keystroke, Format,
+% OnFocus, OnBlur, and Calculate events.
+%
+% \paragraph*{Demo files:} Four sample files are provided: \texttt{gh-eforms.tex}, \texttt{gh-hyperref.tex},
+% \texttt{gh-fmts-eforms.tex}, and \texttt{gh-fmts-hyperref.tex}.
+%
+% \section{Documentation and Code}
+%
+% The \pkg{eforms} package is preferred, but you can use the form field macros of \pkg{hyperref}.
+% Any unrecognized options specified for the \pkg{grayhints} package
+% are passed on to \pkg{insdljs}. If the document
+% author does not want to use \pkg{eforms}, he/she can pass the option \opt{usehyforms}\IndexOpt{usehyforms} to use the form
+% fields of \pkg{hyperref}, in this case \pkg{insdljs} is required. For the last option, \opt{nodljs}
+% is for users of \pkg{hyperref} forms who do not want to use \pkg{insdljs}. In the latter case,
+% the option \opt{usehyforms} should not be used for that will include \pkg{insdljs}.
+% \begin{macrocode}
+\DeclareOption{usehyforms}{%
+ \def\FormsRequirement{\RequirePackage{insdljs}[2017/03/02]}}
+\def\FormsRequirement{\RequirePackage{eforms}[2017/02/27]}
+% \end{macrocode}
+% The \IndexOpt{usealtadobe}\opt{usealtadobe} option is deprecated, the function definitions
+% are automatically loaded unless the \opt{nocalcs} or \opt{nodljs} option is taken.
+% \changes{v1.1}{2018/10/04}{Deprecated the \string\opt{usealtadobe} option, now automatically loaded}
+% \begin{macrocode}
+\DeclareOption{usealtadobe}{\PackageWarningNoLine{grayhints}
+ {The `usealtadobe' option is now deprecated.\MessageBreak
+ The alternate functions are automatically loaded.\MessageBreak
+ Please remove this grayhints package option}}
+% \end{macrocode}
+% \leavevmode\IndexOpt{nocalcs} If this option is taken, the document
+% JavaScript function \texttt{AllowCalc()} is not embedded in the document. The
+% implications are that you are not using any calculation fields.
+% \begin{macrocode}
+\DeclareOption{nocalcs}{\let\nocalcs\endinput}
+\let\nocalcs\relax
+% \end{macrocode}
+% \leavevmode\IndexOpt{nodljs} When this option is specified, there are no
+% requirements placed on this package; that is, neither \pkg{eforms}
+% nor \pkg{insdljs} are required.
+% \begin{macrocode}
+\DeclareOption{nodljs}{\let\FormsRequirement\relax
+ \let\nodljsend\endinput}
+\let\nodljsend\relax
+\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{insdljs}}
+\ProcessOptions
+\FormsRequirement
+% \end{macrocode}
+% We include \texttt{eqcolor.def}, a component of \pkg{exerquiz} to help parse colors,
+% and to match JS colors with PDF colors.
+% \begin{macrocode}
+\@ifundefined{jsColor}{\let\eq@YES=y\let\eq@NO=n%
+ \InputIfFileExists{eqcolor.def}
+ {\PackageInfo{grayhints}{Inputting eqcolor.def from exerquiz}}
+ {\PackageError{grayhints}{cannot find eqcolor.def belonging
+ to exerquiz}{Refresh your file name database and try again.}}
+}{}
+% \end{macrocode}
+%
+% \subsection{JavaScript snippets for Field JavaScript}
+% Code snippets are inserted in to the Format, Calculate,
+% OnFocus, and OnBlur events, as illustrated above.
+%
+% \begin{macro}{\normalGrayColors}\hspace{-\marginparsep}\thinspace
+% \darg{\ameta{normalcolor}}\darg{\ameta{graycolor}} There are two colors
+% in play, the normal color of the text field (\ameta{normalcolor}) and
+% the color of the ``grayed'' text (\ameta{graycolor}). We set the defaults
+% to \texttt{color.black} and \texttt{color.ltGray}, respectively. The two parameters
+% are JavaScipt colors: array type \texttt{["RGB", 1, 0, 0]}, or predefined type
+% \texttt{color.blue}. The command \cs{jsColor} is used to assign colors (taken from
+% \texttt{eqcolor.def} of \pkg{exerquiz}).
+% \begin{macrocode}
+\newcommand{\normalGrayColors}[2]{\def\gh@rgi{#1}\def\gh@rgii{#2}%
+ \ifx\gh@rgi\@empty\else
+ \jsColor\gh@normalcolor{#1}\gh@chkTr@nsparency\fi
+ \ifx\gh@rgii\@empty\else\jsColor\gh@graycolor{#2}\m@tchGray\fi}
+\def\gh@normalcolor{}\def\gh@graycolor{}
+\AtEndOfPackage{\normalGrayColors{color.black}{color.ltGray}}
+% \end{macrocode}
+% \end{macro}
+% There are several predefined JavaScript colors the user can specify. We need to
+% convert them to PDF color too.
+% \begin{macrocode}
+\definecolor{ltGray}{gray}{0.75}
+\definecolor{gray}{gray}{.5}
+\definecolor{dkGray}{gray}{.25}
+\def\gh@pd@transparent{ltGray}\def\gh@transparent{transparent}
+\def\gh@pd@black{black}\def\gh@pd@white{white}
+\def\gh@pd@dkGray{dkGray}\def\gh@pd@gray{gray}\def\gh@pd@ltGray{ltGray}
+\def\gh@pd@red{red}\def\gh@pd@green{green}\def\gh@pd@blue{blue}
+\def\gh@pd@cyan{cyan}\def\gh@pd@magenta{magenta}
+\def\gh@pd@yellow{yellow}
+% \end{macrocode}
+% Convert the JS color for \cs{gh@graycolor} to a matching PDF color that can be
+% used by the \cs{textColor} property of a form field. Here, we use commands defined
+% in the \texttt{eqcolor.def} file from \pkg{exerquiz}. This command defines the user
+% command \DescribeMacro{\matchGray}\cs{matchGray}.
+% \begin{macrocode}
+\def\m@tchGray{\eq@checkRawJSColor{\gh@graycolor}%
+ \ifx\eqpredefineJSCol\eq@NO
+% \end{macrocode}
+% \cs{gh@graycolor} is a JavaScript array
+% \begin{macrocode}
+ \let\matchGray\@empty
+ \expandafter\gh@extr@ctJSModelInfo\gh@graycolor\@nil
+ \ifx\@rgi\@empty\else\edef\matchGray{\@rgi}\fi
+ \ifx\@rgii\@empty\else\edef\matchGray{\matchGray\space\@rgii}\fi
+ \ifx\@rgiii\@empty\else
+ \edef\matchGray{\matchGray\space\@rgiii}\fi
+ \ifx\@rgiv\@empty\else\edef\matchGray{\matchGray\space\@rgiv}\fi
+ \else
+% \end{macrocode}
+% \cs{gh@graycolor} is a predefined color (\texttt{color.ltGray})
+% \begin{macrocode}
+ \expandafter\gh@getColorFromPrefined\gh@graycolor\@nil
+ \@ifundefined{gh@pd@\pd@color}{%
+ \def\gh@graycolor{color.ltGray}\def\pd@color{ltGray}%
+ \PackageWarning{grayhints}
+ {The color.\pd@color\space is undefined,\MessageBreak
+ substituting color.ltGray}}{\ifx\pd@color\gh@transparent
+ \def\gh@graycolor{color.ltGray}\def\pd@color{ltGray}%
+ \PackageWarning{grayhints}
+ {A transparent color is not supported,\MessageBreak
+ using color.ltGray instead}\fi
+ }%
+ \edef\matchGray{\@nameuse{gh@pd@\pd@color}}%
+ \fi}
+\def\gh@chkTr@nsparency{\eq@checkRawJSColor{\gh@normalcolor}%
+ \ifx\eqpredefineJSCol\eq@YES
+ \expandafter\gh@getColorFromPrefined\gh@normalcolor\@nil
+ \@ifundefined{gh@pd@\pd@color}{\def\gh@normalcolor{color.black}%
+ \PackageWarning{grayhints}
+ {The color.\pd@color\space is undefined,\MessageBreak
+ substituting color.black}}{}%
+ \ifx\pd@color\gh@transparent\def\gh@normalcolor{color.black}%
+ \PackageWarning{grayhints}
+ {A transparent color is not supported,\MessageBreak
+ using color.black instead}\fi
+ \fi
+}
+% \end{macrocode}
+% Various supporting macros to extract information.
+% \begin{macrocode}
+\def\gh@extr@ctJSModelInfo[#1,#2]\@nil{%
+ \gh@getspecv@lues#2,,,,\@nil}%
+\def\gh@getspecv@lues#1,#2,#3,#4,#5\@nil{%
+ \def\@rgi{#1}\def\@rgii{#2}\def\@rgiii{#3}\def\@rgiv{#4}}
+\def\gh@getColorFromPrefined color.#1\@nil{\def\pd@color{#1}}
+\def\gh@PriorFormat{event.target.savevalue=event.value;\jsR}
+% \end{macrocode}
+% \DescribeMacro{\FailStringDef} provides a helpful string when the user enters an improper string.
+% This is a language localization command.
+% \changes{v1.2}{2018/11/01}{Added \string\cs{FailStringDef}}
+% \begin{macrocode}
+\newcommand\FailStringDef{continue editing}
+% \end{macrocode}
+% \DescribeMacro{\EnterCommitFailDef} Sets the code for \cs{FailStringDef}.
+% \changes{v1.2}{2018/11/01}{Added \string\cs{EnterCommitFailDef}}
+% \begin{macrocode}
+\newcommand\EnterCommitFailDef{event.value=("\FailStringDef");}
+% \end{macrocode}
+% \DescribeMacro{\EnterCommitFailEvent} Sets the action when the user uses the \textsf{Enter} key to
+% commit date, and the data is not validated.
+% \changes{v1.2}{2018/11/01}{Added \string\cs{EnterCommitFailDef}}
+% \begin{macrocode}
+\def\EnterCommitFailEvent#1{\def\@rgi{#1}\ifx\@rgi\@empty
+ \def\gh@ECFE{\EnterCommitFailDef}\else\def\gh@ECFE{#1}\fi}
+\EnterCommitFailEvent{}
+% \end{macrocode}
+% \DescribeMacro{\CommitSuccessEvent} Set what happens when entering a valid string into a formatting text field
+% \changes{v1.2}{2018/11/01}{Added \string\cs{CommitSuccessEvent}}
+% \begin{macrocode}
+\def\CommitSuccessEvent#1{\def\@rgi{#1}\ifx\@rgi\@empty
+\let\gh@CSE\jsR\else\def\gh@CSE{\jsR\jsT #1\jsR}\fi}
+\let\gh@CSE\jsR
+% \end{macrocode}
+% \begin{macro}{\FmtToGray}\hspace{-\marginparsep}\thinspace
+% \darg{\ameta{grayhint}} This command is placed in the Format event. It places the hint
+% \ameta{grayhint} as the formatting text string when the field is empty.
+% If a built-in Adobe function is also used, use \cs{FmtToGray} after it; for example,
+% \begin{quote}\small
+% |\AAFormat{AFNumber_Format(0,1,0,0,"",true);|\\
+% |\FmtToGray{|\ameta{grayhint}|}}|
+% \end{quote}
+% \begin{macrocode}
+\newcommand\FmtToGray[1]{%
+ if(typeof event.target.savevalue=="undefined"){\jsR\jsT
+ event.target.savevalue="";\jsR\jsT
+ event.target.success=false;\jsR
+ }\jsR
+ if(typeof event.target.ghBuiltin=="undefined")%
+ event.target.ghBuiltin=false;\jsR
+ if(!event.target.ghBuiltin)\gh@PriorFormat
+ event.target.ghBuildtin=false;\jsR\gh@FmtToGray{#1}}
+\def\gh@FmtToGray#1{%
+ if(typeof event.target.saverc=="undefined")%
+ event.target.saverc=true;\jsR
+ if(!event.target.saverc||event.value==""){\jsR\jsT
+ if(event.target.savevalue!=""&&%
+ !event.target.success){\jsR\jsT\gh@ECFE\jsR\jsT
+% \end{macrocode}
+% Here is the only PDF dependent code. The event sequence of close to but not exactly the
+% same as the event sequence for the Adobe PDF viewers, we must insert the following two
+% lines of code to make things work for \app{PDF-XChange Editor}.
+% \begin{macrocode}
+ if(typeof app.pxceInfo!="undefined")%
+ event.target.savevalue="";\jsR\jsT
+ } else {\jsR\jsT\jsT
+ event.target.success=false;\jsR\jsT\jsT
+ event.value=("#1");\jsT\gh@CSE\jsT}\jsR
+ } else {\jsR\jsT
+ event.target.success=true;\gh@CSE}
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\KeyToGray}
+% This command is placed in the Keystroke event. It changes
+% the color to `gray' (\cs{gh@graycolor}) if the field is empty.
+% If a built-in Adobe function is also used, use \cs{KeyToGray} after it; for example,
+% \begin{quote}\small
+% |\AAFormat{AFNumber_Keystroke(0,1,0,0,"",true);|\\
+% |\KeyToGray}|
+% \end{quote}
+% \begin{macrocode}
+\newcommand\KeyToGray{%
+ if(event.willCommit&&event.value!=""&&!event.rc)\jsR\jsT
+ event.target.success=false;\jsR
+ event.target.saverc=event.rc;\jsR
+ event.rc=true;\jsR
+ if(event.willCommit&&event.value=="")%
+ event.target.textColor=\gh@graycolor;\jsR
+ if(event.willCommit)%
+ event.target.savevalue=event.value;
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\CalcToGray}
+% The \cs{CalcToGray} is a Calculate script, it is needed only in a form field that performs
+% a calculation. If a built-in Adobe function is also used, use \cs{KeyToGray} after it; for example,
+%\begin{quote}\small
+% |\AACalculate{var cArray=new Array("Integer");\jsR|\\
+% |if (AllowCalc(cArray)) AFSimple_Calculate("SUM", cArray );\jsR|\\
+% |\CalcToGray}|
+%\end{quote}
+% If the target population might use \app{PDF-XChange Editor}, whose features closely mimic those of
+% \app{Adobe Acrobat Reader}, the use of \cs{CalcToGray} is recommended in all fields.
+% \begin{macrocode}
+\newcommand\CalcToGray{event.target.textColor=%
+ (event.value=="")?\gh@graycolor:\gh@normalcolor;}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\FocusToBlack}
+% A command placed within the OnFocus event. When the field comes into focus, and
+% the field is empty, the color for the text is turned to black. This can be redefined
+% to another color.
+%
+% \item (2018/10/04) We increase the complexity with the goal of getting a better user experience.
+% \begin{macrocode}
+\newcommand\FocusToBlack{%
+ if (typeof event.target.success=="undefined")%
+ event.target.success=false;\jsR
+ if(event.target.valueAsString==""%
+ ||!event.target.success)\jsR\jsT
+ event.target.textColor=\gh@normalcolor;
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\BlurToBlack}
+% A command placed within the OnBlur event. It sets the text color to gray or black,
+% depending on whether the field is empty or not. My be redefined with different colors.
+%
+% \item (2018/10/04) We increase the complexity with the goal of getting a better user experience.
+% \begin{macrocode}
+\newcommand\BlurToBlack{%
+ if (!event.target.success||event.target.valueAsString=="")\jsR\jsT
+ this.resetForm(event.target.name);\jsR
+ event.target.savevalue="";\jsR
+ event.target.textColor=(!event.target.success||%
+ event.target.valueAsString=="")?\gh@graycolor:\gh@normalcolor;
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{\texorpdfstring{\LaTeX}{LaTeX} commands for built-in functions}
+% We define a series of commands as a convenience to the user. The arguments of each
+% are the JavaScript argument enclosed in parentheses.\medskip\par
+% \noindent
+% \DescribeMacro{\NumKey}\cs{NumKey} for processing keystrokes for numbers, and \DescribeMacro{\NumFmt}
+% \cs{NumFmt} formats a number according to its arguments.
+% \begin{macrocode}
+\def\NumKey{EFNumber_Keystroke}
+\def\NumFmt(#1){try{EFNumber_Format(#1)}catch(e){}}
+% \end{macrocode}
+% \DescribeMacro{\DateKey}\cs{DateKey} and \DescribeMacro{\DateFmt}\cs{DateFmt} process the keystroke
+% and format events for a date.
+% \begin{macrocode}
+\def\DateKey{EFDate_Keystroke}
+\def\DateFmt(#1){%
+ AFDate_Format(#1);\jsR
+ event.target.ghBuiltin=true;
+}
+% \end{macrocode}
+% \DescribeMacro{\DateKeyEx}\cs{DateKeyEx} and \DescribeMacro{\DateFmtEx}\cs{DateFmtEx} process the keystroke
+% and format events for a date.
+% \begin{macrocode}
+\def\DateKeyEx{EFDate_KeystrokeEx}
+\def\DateFmtEx(#1){%
+ AFDate_FormatEx(#1);\jsR
+ event.target.ghBuiltin=true;
+}
+% \end{macrocode}
+% \DescribeMacro{\PercentKey}\cs{PercentKey} and \DescribeMacro{\PercentFmt}\cs{PercentFmt} process the keystroke
+% and format events for a number represented as a percentage.
+% \begin{macrocode}
+\def\PercentKey{EFPercent_Keystroke}
+\def\PercentFmt(#1){%
+% \end{macrocode}
+% Avoid the dreaded ``0.00\%'' when the field is blank
+% \begin{macrocode}
+ if(event.value!=""||%
+ (typeof event.target.savevalue!="undefined"&&%
+ event.target.savevalue!=""))%
+ AFPercent_Format(#1);\jsR
+ event.target.ghBuiltin=true;
+}
+% \end{macrocode}
+% \DescribeMacro{\TimeKey}\cs{TimeKey}, \DescribeMacro{\TimeFmt}\cs{TimeFmt}, and
+% \DescribeMacro{\TimeFmtEx}\cs{TimeFmtEx} process the keystroke
+% and format events for a time.
+% \begin{macrocode}
+\def\TimeKey{EFTime_Keystroke}\def\TimeFmt{EFTime_Format}
+\def\TimeFmtEx(#1){try{EFTime_FormatEx(#1)}catch(e){}}
+% \end{macrocode}
+% \DescribeMacro{\SpecialKey}\cs{SpecialKey}, \DescribeMacro{\SpecialKeyEx}\cs{SpecialKeyEx}, and
+% \DescribeMacro{\SpecialFmt}\cs{SpecialFmt} process the keystroke
+% and format events for a special format.
+% \begin{macrocode}
+\def\SpecialKey{EFSpecial_Keystroke}
+\def\SpecialKeyEx{EFSpecial_KeystrokeEx}
+\def\SpecialFmt(#1){try{EFSpecial_Format(#1)}catch(e){}}
+% \end{macrocode}
+% \DescribeMacro{\RangeValidate}\cs{RangeValidate}, \DescribeMacro{\SimpleCalc}\cs{SimpleCalc}, and
+% \DescribeMacro{\MergeChange}\cs{\MergeChange} are specialized JS functions for setting a range
+% resstriction in the validate event, for making a simple calculation in the calculate event, and
+% a general purpose function to merging the current keystroke with event.value, valid for the keystroke
+% event.
+% \begin{macrocode}
+\def\RangeValidate{EFRange_Validate}
+\def\SimpleCalc{EFSimple_Calculate}
+\def\MergeChange{EFMergeChange}
+% \end{macrocode}
+% \subsection{Document JavaScript to support gray hints}
+% The alternate names adobe built-in need to be used for any format function; the normal
+% built-in function names can be otherwise be used.
+% \begin{macrocode}
+\nodljsend
+\begin{insDLJS}{altadbfncs}{gh: Support for Adobe built-in functions}
+var EFNumber_Keystroke=AFNumber_Keystroke;
+function EFNumber_Format(){
+ event.target.savevalue=event.value;
+ event.target.ghBuiltin=true;
+ AFNumber_Format.apply(null,arguments);
+}
+var EFDate_Keystroke=AFDate_Keystroke;
+function EFDate_Format(){
+ event.target.savevalue=event.value;
+ event.target.ghBuiltin=true;
+ AFDate_Format.apply(null,arguments);
+}
+var EFDate_KeystrokeEx=AFDate_KeystrokeEx;
+function EFDate_FormatEx(){
+ event.target.savevalue=event.value;
+ event.target.ghBuiltin=true;
+ AFDate_FormatEx.apply(null,arguments);
+}
+var EFPercent_Keystroke=AFPercent_Keystroke;
+function EFPercent_Format(){
+ event.target.savevalue=event.value;
+ event.target.ghBuiltin=true;
+ AFPercent_Format.apply(null,arguments);
+}
+var EFTime_Keystroke=AFTime_Keystroke;
+function EFTime_Format(){
+ event.target.savevalue=event.value;
+ event.target.ghBuiltin=true;
+ AFTime_Format.apply(null,arguments);
+}
+function EFTime_FormatEx(){
+ event.target.savevalue=event.value;
+ ghBuiltin=true;
+ AFTime_FormatEx.apply(null,arguments);
+}
+var EFSpecial_Keystroke=AFSpecial_Keystroke;
+var EFSpecial_KeystrokeEx=AFSpecial_KeystrokeEx;
+function EFSpecial_Format(){
+ event.target.savevalue=event.value;
+ event.target.ghBuiltin=true;
+ AFSpecial_Format.apply(null,arguments);
+}
+var EFRange_Validate=AFRange_Validate;
+var EFSimple_Calculate=AFSimple_Calculate;
+var EFMergeChange=AFMergeChange;
+\end{insDLJS}
+% \end{macrocode}
+% \cs{nocalcs} is \cs{relax} unless the \opt{nocalcs} option is taken, in which case
+% it is \cs{let} to \cs{endinput}.
+% \begin{macrocode}
+\nocalcs
+\begin{insDLJS}{ghsupport}{gh: Support for the Calculate Event}
+% \end{macrocode}
+% In order to get the gray hints to appear in the terminal field of a calculation group,
+% we cannot perform the calculate when all the dependent fields are empty. \texttt{cArray}
+% is an array of all dependent fields involved in the calculation. The use of this function
+% is illustrated in \texttt{gh-eforms.tex} and \texttt{gh-hyperref.tex}.
+% \begin{macrocode}
+function AllowCalc(cArray) {
+ var f,g;
+ for (var i=0; i<cArray.length; i++) {
+ f=this.getField(cArray[i]);
+ g=f.getArray();
+ for (var j=0; j<g.length; j++)
+ if (g[j].valueAsString!="") return true;
+ }
+ return false;
+}
+\end{insDLJS}
+% \end{macrocode}
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+\endinput
diff --git a/macros/latex/contrib/grayhints/grayhints.ins b/macros/latex/contrib/grayhints/grayhints.ins
new file mode 100644
index 0000000000..254bc29d95
--- /dev/null
+++ b/macros/latex/contrib/grayhints/grayhints.ins
@@ -0,0 +1,58 @@
+%%
+%% 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 2016 D. P. Story
+%% -------------------------------------------
+%%
+%% 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{2018/11/01}
+\def\batchfile{grayhints.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{grayhints.sty}{\from{grayhints.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