summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/pdfmanagement-testphase/l3pdffield.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/pdfmanagement-testphase/l3pdffield.dtx')
-rw-r--r--macros/latex/contrib/pdfmanagement-testphase/l3pdffield.dtx722
1 files changed, 626 insertions, 96 deletions
diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield.dtx b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield.dtx
index e1e5f8bae1..8331ebc127 100644
--- a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield.dtx
+++ b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield.dtx
@@ -73,7 +73,7 @@
% }^^A
% }
%
-% \date{Version 0.95d, released 2021-05-14}
+% \date{Version 0.95e, released 2021-06-14}
%
% \maketitle
% \begin{documentation}
@@ -91,14 +91,26 @@
% \usepackage{l3pdffield-testphase}
% \end{verbatim}
%
-% The code is splitted into various submodules. \texttt{l3pdffield}
-% contains the basic commands to create a form field. The code related to field types
-% like checkboxes are in \texttt{l3pdffield-\emph{type}}, for example
-% \texttt{l3pdffield-checkbox}. Currently only checkboxes have been implemented,
-% other form fields like pushbutton,
-% radio buttons or text fields will follow later.
-% The code doesn't rely on to initialize the form,
-% but it can be used with hyperref.
+% The source code is splitted into various submodules. All code is combined in the
+% sty, but the documentation is in individual PDF.
+% \begin{description}
+% \item[\texttt{l3pdffield}] This contains the basic commands and keys
+% to create a form field.
+% \item[\texttt{l3pdffield-checkbox}] The code to created checkboxes.
+% \item[\texttt{l3pdffield-textfield}] The code to created text fields.
+% \item[\texttt{l3pdffield-radiobutton}] The code to create radio buttons.
+% \item[\texttt{l3pdffield-pushbutton}] The code to create push buttons.
+% \item[\texttt{l3pdffield-choice}] The code to create choice fields (lists and drop-down/combo
+% fields.
+% \item[\texttt{l3pdffield-action}]
+% Code related to actions, mostly submit and reset actions.
+% \item[\texttt{l3pdffield-signature}] (not done yet) Code for signature fields
+% \item[Form initialization] (not done yet) The |\Form| command/environment
+% of \pkg{hyperref} initialize a few things like fonts
+% for text fields which should be moved. It is not strictly necessary to
+% have this code, most examples works without it, but in case of problems it is
+% possible to do the initialization by using the \pkg{hyperref} command.
+% \end{description}
%
% The code requires the new PDF management. The code makes use of
% \pkg{l3pdfxform} to create the form Xobjects of the appearances.
@@ -226,6 +238,30 @@
% are related in a form field. Tests with some PDF viewers
% are needed here.
%
+% \subsection{Tagged PDF}
+%
+% Field annotations are (like link annotations) not part of the page stream. But
+% they are obviously nevertheless meaningful content and must be consider if
+% a PDF is \enquote{tagged}, that means if a structure is added.
+%
+% According to the PDF references fields should be tagged by adding a |Form| structure
+% element containing the object reference to a field annotations. Fields with more than
+% one annotation like radio buttons need a |Form| structure for every one.
+% Additional some cross references to structure relevant object like the parent tree
+% are needed, for more info check the documentation of the \pkg{tagpdf} package.
+%
+% The commands of this module already contain the needed support. So if
+% \pkg{tagpdf} is used and tagging activated the fields will be added as |Form| element
+% to the structure where they are created. It is possible to deactivate tagging for
+% a field annotation by setting the |tag| to false as described below.
+%
+% If lualatex is used tagging require either that \pkg{tagpdf} is used with the
+% option |global-mc|, or mc-chunks must be correctly closed manually, as the automatic
+% code can't escape the grouping.
+%
+% It is recommended to use the |TU|/|altname| key to give the field a readable
+% name.
+%
%
% \section{Commands}
% \begin{function}{\pdffield_field:nn,\pdffield_field:Vn}
@@ -263,7 +299,7 @@
%
% \begin{function}{\pdffield_annot:n,\pdffield_annot:V}
% \begin{syntax}
-% \cs{pdffield_field:nn}\Arg{key val list}
+% \cs{pdffield_annot:n}\Arg{key val list}
% \end{syntax}
% This creates a new field annotation.
% It is a widget annotation box created with \cs{pdfannot_widget_box:nnn}, and
@@ -273,6 +309,15 @@
% The command also setup dictionaries to fill the |AP|, |MK| and |AA| dictionaries.
% \end{function}
%
+% \begin{function}{\pdffield_annot_ref_last:}
+% \begin{syntax}
+% \cs{pdffield_annot_ref_last:}
+% \end{syntax}
+% If a tagged PDF should be created, the object
+% of the annotation of a field should be referenced in the Form structure element.
+% This command allows to retrieve the reference to this object.
+% \end{function}
+
% \begin{function}{\pdffield_appearance:nn}
% \begin{syntax}
% \cs{pdffield_appearance:nn}\Arg{name}\Arg{content}
@@ -295,7 +340,14 @@
% |create-style| = \Arg{name}\Arg{key-val}
% \end{syntax}
% This defines a style which can then be used with the |style| key.
-% \Arg{key-val} can be an arbitrary collection of the keys of the module.
+% \Arg{key-val} can be an arbitrary collection of the keys of the module.
+% \end{function}
+%
+% \begin{function}{create-style}
+% \begin{syntax}
+% |style| = \Arg{style}
+% \end{syntax}
+% This uses a style define with the previous |create-style|.
% \end{function}
%
% \begin{function}{preset-checkbox}
@@ -304,7 +356,32 @@
% \end{syntax}
% This allows to set default keys for a checkbox.
% \end{function}
-
+%
+% \begin{function}{preset-radio}
+% \begin{syntax}
+% |preset-radio|=\Arg{key-val}
+% \end{syntax}
+% This allows to set default keys for a radio button.
+% \end{function}
+%
+% \begin{function}{preset-textfield}
+% \begin{syntax}
+% |preset-textfield|=\Arg{key-val}
+% \end{syntax}
+% This allows to set default keys for a text field.
+% \end{function}
+%
+% \section{Special keys}
+%
+% \begin{function}{value,default}
+% \begin{syntax}
+% |value| =\Arg{value}\\
+% |default|=\Arg{value}
+% \end{syntax}
+% These two keys pass the value to a handler which can be redefined.
+% Their exact behaviour depends on field type. Please check their documentation.
+% \end{function}
+%
% \section{Field Keys}
%
% Table~\ref{tab:fieldkeys} summarize the keys which can be used.
@@ -317,7 +394,7 @@
% \begin{tabular}{>{\ttfamily}lllll}
% \toprule
% key & value & required & inheritable &remark\\\midrule
-% parent & field ID & for non-root fields & \\
+% parent & field ID & for non-root fields & \\
% style & style name & & defined with |create-style| \\
% T, name & string & mostly & \\
% TU, altname & string & & \\
@@ -499,42 +576,41 @@
% \end{function}
%
% The following four keys are used to add javascript (\enquote{ECMAScript}) code.
-% The values are currently only passed through \cs{pdf_string_from_unicode:nnN},
-% but this perhaps will have to change. The keys will be ignored if a pdfstandard
+% The values are expanded. It is recommended to store
+% the javascript in a stream object and to pass the object reference, but passing
+% a string (including parentheses) is possible too.
+% The keys will be ignored if a pdfstandard
% is used that prohibits such actions.
%
% \begin{function}{AA/K,keystroke}
% \begin{syntax}
-% |AA/K| = \meta{string (ECMAScript)}\\
-% |keystroke| = \meta{string (ECMAScript)}
+% |AA/K| = \meta{ECMAScript}\\
+% |keystroke| = \meta{ECMAScript}
% \end{syntax}
% This adds a keystroke action to the
-% additional action dictionary. The value is passed through
-% \cs{pdf_string_from_unicode:nnN}. The action is meant for text and choice fields.
-% It is quite unclear if such an action
+% additional action dictionary. The action is meant for text and choice fields.
+% It is quite unclear if such an action
% make sense for non-terminal fields.
% \end{function}
%
% \begin{function}{AA/F,format}
% \begin{syntax}
-% |AA/F| = \meta{string (ECMAScript)}\\
-% |format| = \meta{string (ECMAScript)}
+% |AA/F| = \meta{ECMAScript}\\
+% |format| = \meta{ECMAScript}
% \end{syntax}
% This adds a format action to the
-% additional action dictionary. The value is passed through
-% \cs{pdf_string_from_unicode:nnN}. The action is meant for text and choice fields.
+% additional action dictionary. The action is meant for text and choice fields.
% It is quite unclear if such an action
% make sense for non-terminal fields.
% \end{function}
%
% \begin{function}{AA/V,validate}
% \begin{syntax}
-% |AA/V| = \meta{string (ECMAScript)}\\
-% |validate| = \meta{string (ECMAScript)}
+% |AA/V| = \meta{ECMAScript}\\
+% |validate| = \meta{ECMAScript}
% \end{syntax}
% This adds a validate action to the
-% additional action dictionary. The value is passed through
-% \cs{pdf_string_from_unicode:nnN}. It is quite unclear if such an action
+% additional action dictionary. It is quite unclear if such an action
% make sense for non-terminal fields.
% \end{function}
%
@@ -544,9 +620,23 @@
% |calculate| = \meta{string (ECMAScript)}
% \end{syntax}
% This adds a calculate action to the
-% additional action dictionary. The value is passed through
-% \cs{pdf_string_from_unicode:nnN}. It is quite unclear if such an action
-% make sense for non-terminal fields.
+% additional action dictionary. It is quite unclear if such an action
+% make sense for non-terminal fields.
+% If an calculate action is used, the field will be added to the
+% AcroForm/CO array to define the calculation order. The order can
+% be controlled through the following key |sortkey|.
+% \end{function}
+%
+% \begin{function}{sortkey}
+% \begin{syntax}
+% |sortkey| = \meta{string}
+% \end{syntax}
+% This sets a sortkey for fields with calculate action.
+% The sortkeys are sorted lexically with |\str_compare:nNnTF|.
+% fields without sortkey will get an empty sortkey and so be at the begin,
+% the order of fields with the same sortkey is not defined.
+% The module only sorts fields created with the commands of this module, the
+% sorting of fields created by \pkg{hyperref} is independant.
% \end{function}
%
% \begin{function}{DA}
@@ -570,6 +660,16 @@
% as it is unclear if there are of any use.
% \end{function}
%
+% \begin{function}{fieldID}
+% \begin{syntax}
+% |fieldID| = \meta{field ID}\\
+% \end{syntax}
+% \emph{For experts only!}
+% This stores \meta{field ID} in an internal variable.
+% The variable is not used by the basic commands,
+% but by the commands to create the various field types.
+% Check their documentation for use cases.
+% \end{function}
% \section{Annot keys}
%
% Table~\ref{tab:annotkeys} summarize the keys which can be used.
@@ -618,17 +718,21 @@
% an already declared field.
% \end{function}
%
-% \begin{function}{AP/N,AP/R,AP/D}
+% \begin{function}{AP/N,appearance,AP/R,rollover-appearance,AP/D,down-appearance}
% \begin{syntax}
% |AP/N| = \meta{appearance name}\\
-% |AP/R| = \meta{appearance name}\\
-% |AP/D| = \meta{appearance name}
+% |appearance| = \meta{appearance name}\\
+% |AP/R| = \meta{rollover appearance name}\\
+% |rollover-appearance| = \meta{rollover appearance name}\\
+% |AP/D| = \meta{down appearance name}\\
+% |down appearance| = \meta{down appearance name}\\
% \end{syntax}
-% This keys set the normal, rollover and down appearance. Alias names are
-% |appearance|, |rollover-appearance| and |down-appearance|.
+% This keys set the normal, rollover and down appearance. The names
+% |appearance|, |rollover-appearance| and |down-appearance| are aliases.
% The value is by default a simple name of an appearance/form Xobject but
% modules like \pkg{l3pdffield-checkbox} change this to allow to add appearances for
-% various states.
+% various states. So check the documentation for the various field types for the
+% exact format of the value.
% \end{function}
%
% \begin{function}{AS}
@@ -636,7 +740,7 @@
% |AS| = \meta{appearance state name}
% \end{syntax}
% This key sets the default appearance state.
-% The value is a name without the starting slash
+% The value is a name \emph{without} the starting slash
% (it is passed through |\pdf_name_from_unicode_e:n|),
% for checkbox for example |Yes|. If used it should typically have the same value
% as the V and DV key of the field.
@@ -657,19 +761,22 @@
%
% \begin{function}{AA/*}
% \begin{syntax}
-% |AA/*| = \meta{string (ECMAScript)}
+% |AA/*| = \meta{ECMAScript}
% \end{syntax}
% * should be one of |F|, |Bl|, |D|, |U|, |E|, |X|, |PO|, |PC|, |PV|, |PI|.
% Alias names for the first six keys are
% |onfocus|, |onblur|, |onmousedown|, |onmouseup|, |onenter|, |onexit|.
% These keys adds then the respective key to the |/AA| dictionary
% of the field annotation object.
-% Their value should be javascript code. The |/AA| dictionary
+% Their value should be javascript code. The value is expanded but not escaped.
+% It is recommended to
+% store the code in a stream object and to use the object reference as value.
+% The |/AA| dictionary
% is suppressed if a pdf/A standard is set.
%
% For example
% \begin{verbatim}
-% onenter={app.alert('Hello');}
+% onenter={(app.alert('Hello');)}
% \end{verbatim}
% \end{function}
%
@@ -724,15 +831,39 @@
% |radiosymbol| for this setting.
% \end{function}
%
-% The remaining key are useful for buttons only, currently no special syntax support
-% is implemented. They will be handled when the code for push buttons is developed and
-% tested.
+% \begin{function}{MK/RC,rollover-caption}
+% \begin{syntax}
+% |MK/RC| = \meta{string}\\
+% |rollover-caption| = \meta{string}
+% \end{syntax}
+% This sets a text for the rollover-caption. \meta{string} is passed through \cs{pdf_string_from_unicode:nnN}
+% and parentheses are added automatically. The key should be used only with
+% pushbuttons. It is unclear if is actually used by the PDF viewer, but the
+% pushbuttons modules uses the argument also to setup the appearance.
+% \end{function}
+%
+% \begin{function}{MK/AC,down-caption}
+% \begin{syntax}
+% |MK/AC| = \meta{string}\\
+% |down-caption| = \meta{string}
+% \end{syntax}
+% This sets a text for the down-caption.
+% \meta{string} is passed through \cs{pdf_string_from_unicode:nnN}
+% and parentheses are added automatically. The key should be used only with
+% pushbuttons. It is unclear if is actually used by the PDF viewer, but the
+% pushbuttons modules uses the argument also to setup the appearance.
+% \end{function}
+%
+% The remaining key are like the two above useful for pushbuttons only.
+% Currently no special syntax support
+% is implemented. They will be handled if needed when the code for
+% push buttons is developed and tested.
% \begin{function}{MK/*}
% \begin{syntax}
% |MK/*| = \meta{various}
% \end{syntax}
% These keys adds the various entries in the \emph{dynamic appearance dictionary}.
-% * should be one of |RC|, |AC|, |I|, |RI|, |IX|, |IF|, |TP|.
+% * should be one of |I|, |RI|, |IX|, |IF|, |TP|.
% The |MK| dictionary can also be added by using |\pdfannot_dict_put:nnn{Widget}{MK}{...}|
% but the two methods should not be mixed.
% \end{function}
@@ -740,12 +871,106 @@
% \end{documentation}
%
% \begin{implementation}
+% \DoNotIndex
+% {
+% \\
+% ,\bitset_clear:N
+% ,\bitset_new:Nn
+% ,\bitset_set_false:Nn
+% ,\bitset_set_true:Nn
+% ,\bitset_to_arabic:N
+% ,\bool_new:N
+% ,\clist_map_inline:nn
+% ,\color_export:nnN
+% ,\color_set:nn
+% ,\color_set:nnn
+% ,\cs_new_protected:Npn
+% ,\cs_set_eq:NN
+% ,\cs_set_protected:Npn
+% ,\cs_if_exist:NTF
+% ,\cs_if_exist:NT
+% ,\cs_new:Npn
+% ,\csname
+% ,\dim_eval:n
+% ,\dim_new:N
+% ,\endcsname
+% ,\exp_args:Ne
+% ,\exp_args:Nnx
+% ,\exp_args:NV
+% ,\group_begin:
+% ,\group_end:
+% ,\hbox_to_wd:nn
+% ,\hfill
+% ,\hook_gput_code:nnn
+% ,\int_eval:n
+% ,\l_keys_choice_int
+% ,\keys_define:nn
+% ,\keys_set:nn
+% ,\mode_leave_vertical:
+% ,\msg_error:nnnn
+% ,\msg_error:nnx
+% ,\msg_new:nnn
+% ,\msg_warning:nn
+% ,\msg_warning:nnn
+% ,\msg_info:nnn
+% ,\msg_warning:nnnnn
+% ,\NeedsTeXFormat
+% ,\pdf_name_from_unicode_e:n
+% ,\pdf_object_if_exist:nTF
+% ,\pdf_object_new:nn
+% ,\pdf_object_ref:n
+% ,\pdf_object_ref_last:
+% ,\pdf_object_unnamed_write:nx
+% ,\pdf_object_write:nx
+% ,\pdf_string_from_unicode:nnN
+% ,\pdfannot_box_ref_last:
+% ,\pdfannot_dict_put:nnn
+% ,\pdfannot_dict_put:nnx
+% ,\pdfannot_dict_remove:nn
+% ,\pdfannot_widget_box:nnn
+% ,\pdfdict_if_empty:nTF
+% ,\pdfdict_if_empty:nF
+% ,\pdfdict_new:n
+% ,\pdfdict_put:nnn
+% ,\pdfdict_put:nnx
+% ,\pdfdict_remove:nn
+% ,\pdfdict_use:n
+% ,\pdfmanagement_add:nnn
+% ,\pdfmanagement_add:nnx
+% ,\pdfmeta_standard_verify:nTF
+% ,\pdfmeta_standard_verify:nT
+% ,\pdfmeta_standard_verify:nF
+% ,\pdfxform_if_exist:nTF
+% ,\pdfxform_new:nnn
+% ,\pdfxform_ref:n
+% ,\ProvidesExplPackage
+% ,\rule
+% ,\seq_gput_right:Nn
+% ,\seq_gput_right:cx
+% ,\seq_if_exist:NTF
+% ,\seq_if_exist:cTF
+% ,\seq_new:N
+% ,\seq_new:c
+% ,\seq_use:Nn
+% ,\seq_use:cn
+% ,\str_if_empty:NTF
+% ,\str_if_in:NnTF
+% ,\str_if_in:NnT
+% ,\str_new:N
+% ,\tl_if_empty:NTF
+% ,\tl_if_empty:NF
+% ,\tl_if_empty:nTF
+% ,\tl_if_head_eq_charcode:nNTF
+% ,\tl_new:N
+% ,\tl_set:Nn
+% ,\tl_to_str:n
+% }
% \section{\pkg{l3pdffield} Implementation}
% \begin{macrocode}
%<*package>
%<@@=pdffield>
\NeedsTeXFormat{LaTeX2e}
-\ProvidesExplPackage{l3pdffield-testphase}{2021-05-14}{0.95d}%
+\ProvidesExplPackage{l3pdffield-testphase}{2021-06-14}{0.95e}%
{form fields}
% \end{macrocode}
% \subsection{hyperref specific command}
@@ -756,16 +981,48 @@
%
% \subsection{local variables}
%
+% \begin{variable}
+% {
+% \l_@@_tmpa_str
+% ,\l_@@_tmpb_str
+% ,\l_@@_tmpa_tl
+% ,\l_@@_tmpa_keys_tl
+% ,\l_@@_currentparent_tl
+% ,\l_@@_fieldID_tl
+% ,\l_@@_caption_tl
+% ,\l_@@_rollover_caption_tl
+% ,\l_@@_down_caption_tl
+% ,\g_@@_CO_sortkeys_prop
+% ,\l_@@_CO_sortkey_str
+% ,\g_@@_annot_ref_last_tl
+% ,\l_@@_tag_bool
+% }
+% Some tmp variables, and a variable for the current parent and the
+% current fieldID.
% \begin{macrocode}
\str_new:N \l_@@_tmpa_str
+\str_new:N \l_@@_tmpb_str
\tl_new:N \l_@@_tmpa_tl
\tl_new:N \l_@@_tmpa_keys_tl
+\tl_new:N \l_@@_currentparent_tl
+\tl_new:N \l_@@_fieldID_tl
+\tl_new:N \l_@@_caption_tl
+\tl_new:N \l_@@_rollover_caption_tl
+\tl_new:N \l_@@_down_caption_tl
+\prop_new:N \g_@@_CO_sortkeys_prop
+\seq_new:N \g_@@_CO_sortkeys_seq
+\str_new:N \l_@@_CO_sortkey_str
+\tl_new:N \g_@@_annot_ref_last_tl
+\bool_new:N \l_@@_tag_bool
+\bool_set_true:N \l_@@_tag_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macrocode}
\cs_new_protected:Npn \@@_tmpa:n #1 {}
\cs_new_protected:Npn \@@_tmpa:nn #1 #2 {}
-\tl_new:N \l_@@_currentparent_tl
-\tl_new:N \l_@@_fieldID_tl
% \end{macrocode}
-%
+
% \subsection{messages}
% \begin{macrocode}
\msg_new:nnn {pdffield}{no-period}
@@ -797,6 +1054,10 @@
The~parent~field~'#1'~doesn't~exist\\
Create~it~with~\tl_to_str:n{\pdffield_field:nn}
}
+\msg_new:nnn {pdffield}{key-ignored}
+ {
+ key~`#1`~has~no~function~and~is~ignored
+ }
% \end{macrocode}
% An auxiliary command to disable some keys
@@ -815,8 +1076,8 @@
% \end{macrocode}
% \end{macro}
% \subsection{bitsets}
-% A bitset for the field flag Ff
-% and an internal copy of the annot bitset.
+% \begin{macro}{\l_@@_Ff_bitset,\l_@@_F_bitset}
+% The field and the annot bitset.
% \begin{macrocode}
\bitset_new:Nn \l_@@_Ff_bitset
{
@@ -886,6 +1147,7 @@
lockedcontents = 10
}
% \end{macrocode}
+% \end{macro}
% \subsection{The field dictionary}
% The field dictionary is the main object.
% To be able to set values from the outside it will use a
@@ -893,9 +1155,8 @@
% \begin{macrocode}
\pdfdict_new:n {l_@@/field}
\pdfdict_new:n {l_@@/field/AA}
-\bool_new:N \l_@@_root_field_bool
% \end{macrocode}
-% \begin{macro}{\@@_field:n}
+% \begin{macro}{\@@_field:n,\pdffield_field:nn}
% \begin{syntax}
% \cs{@@_field:n}\Arg{field ID}
% \end{syntax}
@@ -943,6 +1204,14 @@
{l_@@/field}
{AA}
{\pdf_object_ref_last:}
+ \pdfdict_get:nnN {l_@@/field/AA}{C}\l_@@_tmpa_tl
+ \quark_if_no_value:NF \l_@@_tmpa_tl
+ {
+ \prop_gput:Nxx\g_@@_CO_sortkeys_prop
+ { \pdf_object_ref:n {@@/field/#1} }{ \l_@@_CO_sortkey_str }
+ \seq_gput_right:Nx\g_@@_CO_sortkeys_seq
+ { \pdf_object_ref:n {@@/field/#1} }
+ }
}
}
\hook_gput_code:nnn {shipout/lastpage}{pdffield} %xetex needs this ...
@@ -954,6 +1223,27 @@
}
\pdf_object_write:nx {@@/field/#1} { \pdfdict_use:n {l_@@/field} }
}
+
+\hook_gput_code:nnn {shipout/lastpage}{pdffield}
+ {
+ \prop_if_empty:NF \g_@@_CO_sortkeys_prop
+ {
+ \seq_sort:Nn \g_@@_CO_sortkeys_seq
+ {
+ \str_compare:eNeTF
+ { \prop_item:Nn \g_@@_CO_sortkeys_prop {#1} }
+ >
+ { \prop_item:Nn \g_@@_CO_sortkeys_prop {#2} }
+ { \sort_return_swapped: }
+ { \sort_return_same: }
+ }
+ \pdfmanagement_add:nnx
+ { Catalog / AcroForm }
+ { CO }
+ { \seq_use:Nn \g_@@_CO_sortkeys_seq{~} }
+ }
+ }
+
\cs_new_protected:Npn \pdffield_field:nn #1 #2
{
\group_begin:
@@ -968,7 +1258,7 @@
% We assume that the annotation should really occupy space on the page and
% leave vertical mode.
%
-% \begin{macro}{\@@_annot:}
+% \begin{macro}{\@@_annot:,\pdffield_annot:n}
% The command doesn't add grouping, so should only be used inside a group.
%
% \begin{macrocode}
@@ -983,6 +1273,7 @@
\bitset_set_false:Nn \l_@@_F_bitset {NoView}
}
\pdfannot_dict_put:nnx {widget}{F}{ \bitset_to_arabic:N \l_@@_F_bitset }
+ \@@_tag_add_struct_parent:
\tl_if_empty:NF \l_@@_currentparent_tl
{
\exp_args:Ne
@@ -999,6 +1290,7 @@
}
}
\mode_leave_vertical:
+ \@@_tag_struct_begin:
\hbox_to_wd:nn
{ \l_@@_annot_wd_dim }
{
@@ -1009,13 +1301,16 @@
{ \l_@@_annot_dp_dim }
\hfill
}
+ \tl_gset:Nx \g_@@_annot_ref_last_tl { \pdfannot_box_ref_last: }
+ \exp_args:NV \@@_tag_add_objr:n \g_@@_annot_ref_last_tl
+ \@@_tag_struct_end:
\tl_if_empty:NF \l_@@_currentparent_tl
{
\seq_if_exist:cTF {g_@@_field/Kids/\l_@@_currentparent_tl _seq}
{
\seq_gput_right:cx
{g_@@_field/Kids/\l_@@_currentparent_tl _seq}
- { \pdfannot_box_ref_last:}
+ { \g_@@_annot_ref_last_tl }
}
{
\msg_error:nnx { pdffield}{parent-field-missing}{\l_@@_currentparent_tl}
@@ -1032,7 +1327,68 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\pdffield_annot_ref_last:}
+% \begin{macrocode}
+\cs_new:Npn \pdffield_annot_ref_last: { \g_@@_annot_ref_last_tl }
+% \end{macrocode}
+% \end{macro}
+% \subsection{Tagging}
+% \begin{macro}
+% {
+% \@@_tag_add_struct_parent:,
+% \@@_tag_add_objr:n,
+% \@@_tag_struct_begin:
+% \@@_tag_struct_end:
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_tag_add_struct_parent: {}
+\cs_new_protected:Npn \@@_tag_add_objr:n #1 {}
+\cs_new_protected:Npn \@@_tag_struct_begin: {}
+\cs_new_protected:Npn \@@_tag_struct_end: {}
+\hook_gput_code:nnn {begindocument} { l3pdffield }
+ {
+ \cs_if_exist:NT \tag_if_active:T
+ {
+ \tag_if_active:T
+ {
+ \cs_set_protected:Npn \@@_tag_add_struct_parent:
+ {
+ \bool_if:NT \l_@@_tag_bool
+ {
+ \pdfannot_dict_put:nnx {widget}{StructParent}{ \tag_struct_parent_int: }
+ }
+ }
+ \cs_set_protected:Npn \@@_tag_add_objr:n #1
+ {
+ \bool_if:NT \l_@@_tag_bool
+ {
+ \exp_args:Nnx
+ \tag_struct_insert_annot:nn {#1}{ \tag_struct_parent_int: }
+ }
+ }
+ \cs_set_protected:Npn \@@_tag_struct_begin:
+ {
+ \bool_if:NT \l_@@_tag_bool
+ {
+ \tag_mc_end_push:
+ \tag_struct_begin:n{tag=Form}
+ }
+ }
+ \cs_set_protected:Npn \@@_tag_struct_end:
+ {
+ \bool_if:NT \l_@@_tag_bool
+ {
+ \tag_struct_end:
+ \tag_mc_begin_pop:n{}
+ }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
% \subsection{auxiliary command for color keys}
+% \begin{macro}{\@@_color_set:nn }
% \begin{macrocode}
\cs_new_protected:Npn \@@_color_set:nn #1 #2
{
@@ -1051,16 +1407,25 @@
}
% \end{macrocode}
+% \end{macro}
% \subsection{Field keys}
% The names. The main name should not be empty, it is added to the dictionary
% when the field is created. A new name means a new field.
% The other names can only be set when the field is created,
% so we put them in the field group.
+% \begin{macro}{\@@_V_handler:nN}
+% Values (V and DV) need different handling in the various field types. So
+% it uses a handler which can be redefined locally. By default it simply stores
+% the value in a tl var.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_value_handler:nN #1#2
+\cs_new_protected:Npn \@@_V_handler:nN #1#2
{
\tl_set:Nn #2 {#1}
}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{parent,T,name,TU,altname,TM,mappingname}
+% \begin{macrocode}
\keys_define:nn { pdffield }
{
,parent .tl_set:N = \l_@@_currentparent_tl
@@ -1094,7 +1459,7 @@
\pdfdict_remove:nn { l_@@/field }{TU}
}
{
- \pdf_string_from_unicode:nnN {utf8/string}{#1}\l_@@_tmpa_str
+ \pdf_string_from_unicode:nnN {utf16/hex}{#1}\l_@@_tmpa_str
\pdfdict_put:nnx { l_@@/field }{TU}{\l_@@_tmpa_str}
}
}
@@ -1108,13 +1473,32 @@
\pdfdict_remove:nn { l_@@/field }{TM}
}
{
- \pdf_string_from_unicode:nnN {utf8/string}{#1}\l_@@_tmpa_str
+ \pdf_string_from_unicode:nnN {utf16/hex}{#1}\l_@@_tmpa_str
\pdfdict_put:nnx { l_@@/field }{TM}{\l_@@_tmpa_str}
}
}
,TM .groups:n = {field}
,mappingname .meta:n = {TM={#1}}
,mappingname .groups:n = {field}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{fieldID}
+% For some field types we need a fieldID.
+%
+% \begin{macrocode}
+\keys_define:nn { pdffield }
+ {
+ fieldID .tl_set:N = \l_@@_fieldID_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{FT,V,DV,MaxLen,Lock,SV,Opt,TI,I}
+% \begin{macrocode}
+\keys_define:nn{pdffield}
+ {
,FT .choices:nn =
{ Btn, Tx, Ch, Sig }
{
@@ -1128,7 +1512,7 @@
\pdfdict_remove:nn { l_@@/field }{V}
}
{
- \@@_value_handler:nN{#1}\l_@@_tmpa_str
+ \@@_V_handler:nN{#1}\l_@@_tmpa_str
\pdfdict_put:nnx { l_@@/field }{V}{ \l_@@_tmpa_str }
}
}
@@ -1140,7 +1524,7 @@
\pdfdict_remove:nn { l_@@/field }{DV}
}
{
- \@@_value_handler:nN{#1}\l_@@_tmpa_str
+ \@@_V_handler:nN{#1}\l_@@_tmpa_str
\pdfdict_put:nnx { l_@@/field }{DV}{ \l_@@_tmpa_str }
}
}
@@ -1213,8 +1597,9 @@
,I .groups:n = {field}
}
% \end{macrocode}
-
+% \end{macro}
% Flags. We don't add lots of individual keys but map the key names directly
+% \begin{macro}{setFf,setfieldflags,unsetFf,unsetfieldflags}
% \begin{macrocode}
\keys_define:nn { pdffield }
{
@@ -1241,7 +1626,12 @@
}
% \end{macrocode}
-%
+% \end{macro}
+% \begin{macro}
+% {
+% AA/K,keystroke,AA/F,format,
+% AA/V,validate,AA/C,calculate
+% }
% Keys for the AA dictionary. They all trigger a javascript option.
% K=keystroke, F=format, V=validate, C=calculate
% \begin{macrocode}
@@ -1251,15 +1641,14 @@
{
AA/#1 .code:n =
{
- \pdf_string_from_unicode:nnN {utf8/string-raw}{##1}\l_@@_tmpa_str
- \str_if_empty:NTF \l_@@_tmpa_str
+ \tl_if_empty:nTF {#1}
{
\pdfdict_remove:nn {l_@@/field/AA}{#1}
}
{
\pdfdict_put:nnx {l_@@/field/AA}
{#1}
- {<</S/JavaScript/JS(\l_@@_tmpa_str)>>}
+ {<</S/JavaScript/JS\c_space_tl ##1>>}
}
},
AA/#1 .groups:n = {field}
@@ -1282,9 +1671,15 @@
\@@_tmpa:nn {validate} {V}
\@@_tmpa:nn {calculate}{C}
-
+\keys_define:nn {pdffield}
+ {
+ sortkey .code:n = {\str_set:Nx \l_@@_CO_sortkey_str {\tl_to_str:n{#1}}}
+ }
% \end{macrocode}
+% \end{macro}
%
+% \begin{macro}{DA,Q,align,DS,RV}
+% The following keys are related to textfield and their format.
% \begin{macrocode}
\keys_define:nn { pdffield }
{
@@ -1318,15 +1713,24 @@
,RV .groups:n = {field}
}
% \end{macrocode}
-%
+% \end{macro}
% \subsection{Annotation keys}
% The size of the field annotation
-%
+% \begin{variable}
+% {
+% \l_@@_annot_ht_dim,
+% \l_@@_annot_wd_dim,
+% \l_@@_annot_dp_dim
+% }
% \begin{macrocode}
\dim_new:N \l_@@_annot_ht_dim
\dim_new:N \l_@@_annot_wd_dim
\dim_new:N \l_@@_annot_dp_dim
-
+% \end{macrocode}
+% \end{variable}
+% \begin{macro}{width,height,depth}
+% The size of the field annotation.
+% \begin{macrocode}
\keys_define:nn { pdffield }
{
,width .dim_set:N = \l_@@_annot_wd_dim
@@ -1337,7 +1741,37 @@
,depth .initial:n = 0pt
}
% \end{macrocode}
-%
+% \end{macro}
+% \begin{macro}{tag}
+% to disable tagging locall
+% \begin{macrocode}
+\keys_define:nn { pdffield }
+ {
+ ,tag .bool_set:N = \l_@@_tag_bool
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@@_appearance_handler:nnn}
+% Appearances have to be handled in various ways, so we use a handler, that
+% the field types can redefine if needed.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_appearance_handler:nnn #1#2#3
+ {
+ \pdfxform_if_exist:nTF { #1 }
+ {
+ \pdfannot_dict_put:nnx {widget/AP}{#2}
+ {
+ \pdfxform_ref:n {#1}
+ }
+ }
+ {
+ \msg_error:nnnn{pdffield}{appearance-missing}{#1}{#3}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{AS,AP/N,appearance,AP/R,rollover-appearance,AP/D,down-appearance}
+% The key for the default appearance and the various types.
% \begin{macrocode}
\keys_define:nn { pdffield }
{
@@ -1354,19 +1788,6 @@
}
,AS .groups:n = annot
}
-\cs_new_protected:Npn \@@_appearance_handler:nnn #1#2#3
- {
- \pdfxform_if_exist:nTF { #1 }
- {
- \pdfannot_dict_put:nnx {widget/AP}{#2}
- {
- \pdfxform_ref:n {#1}
- }
- }
- {
- \msg_error:nnnn{pdffield}{appearance-missing}{#1}{#3}
- }
- }
\keys_define:nn { pdffield }
{
AP/N .code:n =
@@ -1381,6 +1802,7 @@
}
,AP/N .groups:n = annot
,appearance .meta:n = {AP/N={#1}}
+ ,appearance .groups:n = annot
}
\keys_define:nn { pdffield }
{
@@ -1396,6 +1818,7 @@
}
,AP/R .groups:n = annot
,rollover-appearance .meta:n = {AP/R={#1}}
+ ,rollover-appearance .groups:n = annot
}
\keys_define:nn { pdffield }
{
@@ -1406,13 +1829,18 @@
\pdfannot_dict_remove:nn { widget/AP }{D}
}
{
- \@@_appearance_handler:nnn {#1}{D}{rollover}
+ \@@_appearance_handler:nnn {#1}{D}{down}
}
}
,AP/D .groups:n = annot
,down-appearance .meta:n = {AP/D={#1}}
+ ,down-appearance .groups:n = annot
}
-
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{MK/R,rotate,MK/BC,bordercolor,MK/BG,backgroundcolor,MK/CA,caption}
+% This are the keys for the dynamic appearance. A number are not handled yet fully.
+% \begin{macrocode}
\keys_define:nn { pdffield }
{
MK/R .choices:nn = {0,90,180,270}
@@ -1460,7 +1888,7 @@
}
}
,MK/BG .groups:n = annot
- ,bordercolor .meta:n = {MK/BG=#1}
+ ,backgroundcolor .meta:n = {MK/BG=#1}
}
@@ -1468,6 +1896,7 @@
{
MK/CA .code:n =
{
+ \tl_set:Nn \l_@@_caption_tl {#1}
\tl_if_empty:nTF {#1}
{
\pdfannot_dict_remove:nn { widget/MK }{CA}
@@ -1481,6 +1910,49 @@
,caption .meta:n = {MK/CA=#1}
}
+\keys_define:nn { pdffield }
+ {
+ MK/RC .code:n =
+ {
+ \tl_set:Nn \l_@@_rollover_caption_tl {#1}
+ \tl_if_empty:nTF {#1}
+ {
+ \pdfannot_dict_remove:nn { widget/MK }{RC}
+ }
+ {
+ \pdf_string_from_unicode:nnN {utf8/string}{#1}\l_@@_tmpa_str
+ \pdfannot_dict_put:nnx {widget/MK}{RC}{\l_@@_tmpa_str}
+ }
+ }
+ ,MK/RC .groups:n = annot
+ ,rollover-caption .meta:n = {MK/RC=#1}
+ }
+
+\keys_define:nn { pdffield }
+ {
+ MK/AC .code:n =
+ {
+ \tl_set:Nn \l_@@_down_caption_tl {#1}
+ \tl_if_empty:nTF {#1}
+ {
+ \pdfannot_dict_remove:nn { widget/MK }{AC}
+ }
+ {
+ \pdf_string_from_unicode:nnN {utf8/string}{#1}\l_@@_tmpa_str
+ \pdfannot_dict_put:nnx {widget/MK}{AC}{\l_@@_tmpa_str}
+ }
+ }
+ ,MK/AC .groups:n = annot
+ ,down-caption .meta:n = {MK/AC=#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{MK/I,MK/RI,MK/IX,MK/IF,MK/TP}
+% The following keys are pushputtons only. Currently there is no special handling
+% involved as it is unclear if they are useful.
+% \begin{macrocode}
+
\cs_set_protected:Npn \@@_tmpa:n #1
{
\keys_define:nn { pdffield }
@@ -1489,7 +1961,7 @@
{
\tl_if_empty:nTF {##1}
{
- \pdfannot_dict_remove:nn { widget/AP }{#1}
+ \pdfannot_dict_remove:nn { widget/MK }{#1}
}
{
\pdfannot_dict_put:nnx {widget/MK}{#1}{##1}
@@ -1499,10 +1971,13 @@
}
}
-\clist_map_inline:nn {RC,AC,I,RI,IX,IF,TP}
+\clist_map_inline:nn {I,RI,IX,IF,TP}
{ \@@_tmpa:n {#1} }
% \end{macrocode}
+% \end{macro}
+%
% Flags.
+% \begin{macro}{setF,setannotflags,unsetF,unsetannotflags}
% \begin{macrocode}
\keys_define:nn { pdffield }
{
@@ -1530,11 +2005,17 @@
}
% \end{macrocode}
-%
+% \end{macro}
% Keys for the AA dictionary. They all trigger a javascript option.
% Fo = onfocus, Bl = onblur, D = onmousedown, U = onmouseup,
% E = onenter, X = onexit, PO = pageopen, PC = pageclose,
% PV = pagevisible, PI = pageinvisible
+% \begin{macro}
+% {
+% AA/Fo,onfocus, AA/Bl,onblur, AA/D,onmousedown, AA/U,onmouseup,
+% AA/E,onenter, AA/X,onexit, AA/PO,pageopen, AA/PC,pageclose,
+% AA/PV,pagevisible, AA/PI,pageinvisible
+% }
% \begin{macrocode}
\cs_set_protected:Npn \@@_tmpa:n #1 %
{
@@ -1542,15 +2023,14 @@
{
AA/#1 .code:n =
{
- \pdf_string_from_unicode:nnN {utf8/string-raw}{##1}\l_@@_tmpa_str
- \str_if_empty:NTF \l_@@_tmpa_str
+ \tl_if_empty:nTF {#1}
{
\pdfannot_dict_remove:nn {widget/AA}{#1}
}
{
\pdfannot_dict_put:nnx {widget/AA}
{#1}
- {<</S/JavaScript/JS(\l_@@_tmpa_str)>>}
+ {<</S/JavaScript/JS\c_space_tl##1>>}
}
},
,AA/#1 .groups:n = annot
@@ -1575,8 +2055,9 @@
\@@_tmpa:nn {onenter} {E}
\@@_tmpa:nn {onexit} {X}
% \end{macrocode}
+% \end{macro}
% \subsection{Appearances}
-% \begin{macro}{\pdffield_appearance:nn}
+% \begin{macro}{\pdffield_appearance:nn,\pdffield_store_appearance:nn}
% \begin{macrocode}
\cs_new_protected:Npn \pdffield_appearance:nn #1 #2
{
@@ -1587,7 +2068,7 @@
% \end{macrocode}
% \end{macro}
% \subsection{Setup command}
-%
+% \begin{macro}{create-style,preset-checkbox,preset-radio,preset-textfield}
% \begin{macrocode}
\keys_define:nn { pdffield / setup }
{
@@ -1599,6 +2080,13 @@
@@/preset/checkbox .meta:n = {#1},
}
}
+ ,preset-radiobutton .code:n =
+ {
+ \keys_define:nn { pdffield }
+ {
+ @@/preset/radiobutton .meta:n = {#1},
+ }
+ }
,preset-textfield .code:n =
{
\keys_define:nn { pdffield }
@@ -1606,10 +2094,30 @@
@@/preset/textfield .meta:n = {#1},
}
}
+ ,preset-pushbutton .code:n =
+ {
+ \keys_define:nn { pdffield }
+ {
+ @@/preset/pushbutton .meta:n = {#1},
+ }
+ }
+ ,preset-choice .code:n =
+ {
+ \keys_define:nn { pdffield }
+ {
+ @@/preset/choice .meta:n = {#1},
+ }
+ }
}
\keys_set:nn{ pdffield / setup }{preset-checkbox={}}
\keys_set:nn{ pdffield / setup }{preset-textfield={}}
-
+\keys_set:nn{ pdffield / setup }{preset-radiobutton={}}
+\keys_set:nn{ pdffield / setup }{preset-pushbutton={}}
+\keys_set:nn{ pdffield / setup }{preset-choice={}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@@_style_create:nn}
+% \begin{macrocode}
\cs_new_protected:Npn \@@_style_create:nn #1#2
{
\keys_define:nn { pdffield }
@@ -1618,7 +2126,10 @@
}
}
-
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\pdffield_setup:n,style}
+% \begin{macrocode}
\cs_new_protected:Npn \pdffield_setup:n #1
{
\keys_set:nn{ pdffield / setup }{#1}
@@ -1629,6 +2140,25 @@
style .code:n = {\keys_set:nn {pdffield}{@@/style/#1={#1}}}
}
% \end{macrocode}
+% \end{macro}
+% \section{Value keys}
+% \begin{macro}{value,default,\@@_value_handler:n,\@@_default_handler:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_value_handler:n #1
+ {
+ \msg_info:nnn {pdffield}{key-ignored}{value}
+ }
+\cs_new_protected:Npn \@@_default_handler:n #1
+ {
+ \msg_info:nnn {pdffield}{key-ignored}{default}
+ }
+\keys_define:nn {pdffield}
+ {
+ value .code:n = { \@@_value_handler:n {#1} }
+ ,default .code:n = { \@@_default_handler:n {#1}}
+ }
+% \end{macrocode}
+% \end{macro}
% \begin{macrocode}
%</package>
% \end{macrocode}