diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/pdfmanagement-testphase/l3pdffield-choice.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/pdfmanagement-testphase/l3pdffield-choice.dtx | 672 |
1 files changed, 672 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/pdfmanagement-testphase/l3pdffield-choice.dtx b/Master/texmf-dist/source/latex/pdfmanagement-testphase/l3pdffield-choice.dtx new file mode 100644 index 00000000000..630552274a2 --- /dev/null +++ b/Master/texmf-dist/source/latex/pdfmanagement-testphase/l3pdffield-choice.dtx @@ -0,0 +1,672 @@ +% \iffalse meta-comment +% +%% File: l3pdfpdffield-choice.dtx +% +% Copyright (C) 2021 The LaTeX Project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% http://www.latex-project.org/lppl.txt +% +% This file is part of the "LaTeX PDF management testphase bundle" (The Work in LPPL) +% and all files in that bundle must be distributed together. +% +% ----------------------------------------------------------------------- +% +% The development version of the bundle can be found at +% +% https://github.com/latex3/pdfresources +% +% for those people who are interested. +% +%<*driver> +\RequirePackage{pdfmanagement-testphase} +\DeclareDocumentMetadata{} +\makeatletter +\declare@file@substitution{doc.sty}{doc-v3beta.sty} +\makeatother +\documentclass[full]{l3doc} +\usepackage{array,booktabs} +\usepackage{l3pdffield-testphase} +\hypersetup{pdfauthor=The LaTeX Project, + pdftitle=l3pdffield (LaTeX PDF management testphase bundle)} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +%</driver> +% \fi +% \providecommand\hook[1]{\texttt{#1}} +% \title{^^A +% The \pkg{l3pdffield-choice} module\\ Commands to create choice fields ^^A +% \\ \LaTeX{} PDF management testphase bundle +% } +% +% \author{^^A +% The \LaTeX{} Project\thanks +% {^^A +% E-mail: +% \href{mailto:latex-team@latex-project.org} +% {latex-team@latex-project.org}^^A +% }^^A +% } +% +% \date{Version 0.95e, released 2021-06-14} +% +% \maketitle +% \begin{documentation} +% \section{\pkg{l3pdffield-choice} Introduction} +% This is the documentation for choice fields, for general information about form fields +% check the documentation l3pdffield. +% +% +% Please keep in mind +% \begin{itemize} +% \item Not every PDF viewer supports choice field. +% \item The handling can depend on settings in the PDF viewer. In adobe reader for +% example I had to disable an option to avoid that it tries to create an appearance +% itself +% \item Standards like pdf/A disable features of form fields too +% (as you typically can't change the PDF). +% \end{itemize} +% \section{Choice fields} +% +% Choice fields are drop down menus or scrollable lists where +% the user can select one or more entries. They can also contain a field where +% users can insert a free text. The export value and the displayed value can differ. +% Some values can be preselected. +% +% This means that various data will have to be set, and the sorting matters. +% The module here will assume that the various values are stored in sequences: +% +% \ExplSyntaxOn +% \seq_const_from_clist:Nn \c_my_values_seq {hippo,duck,bear} +% \seq_const_from_clist:Nn \c_my_displayvalues_seq {Sieglinde,,Bär} +% \seq_const_from_clist:Nn \c_my_defaultvalues_seq {duck,Bär} %check if export or altname ... +% \ExplSyntaxOff +% +% Only the first sequence is required. +% Empty values in the display sequence are possible, then the normal value is used. +% +% \subsection{Types} +% Choice fields can be a drop down menu (called |Combo|), which can contain an editable +% field. +% +% |setfieldflags={Combo,Edit}| or |setfieldflags={Combo}| +% +% If |Edit| is set, one can also set |DoNotSpellCheck|. +% +% Or they can be a list. +% +% |unsetfieldflags={Combo,Edit,DoNotSpellCheck}| +% +% +% For both types it is possible to set or unset |MultiSelect| and |CommitOnSelChange|. +% +% +% \subsection{Appearance} +% hm .... +% +% \bigskip +% \subsection{Commands} +% \begin{function}{\pdffield_choice:n} +% \begin{syntax} +% \cs{pdffield_choice:n}\Arg{key val list} +% \end{syntax} +% This creates a choice field. +% The list of allowed keys is described below. +% The \meta{key val list} should at least set the name, +% without it the default |choice| is used. Choice fields with the same +% belong to the same field and if changed, the others are changed accordingly. +% The default appearance ... +% +% The first choice field setups the field and so should setup values and field flags. +% \end{function} +% +% +% \subsection{Keys} +% +% The new choice command accept all field and annot keys from l3pdffield. +% A few keys are disabled or are forced to specific values. +% The |appearance| keys have a ... +% behaviour, other keys have other defaults than with the basic commands. +% Additionally there +% are a small number of keys specific to a choice field. +% |value| and |default| have a special meaning. +% +% +% Disabled keys are +% \begin{itemize} +% \item |V|, |DV|, |AS|: they are set by the other keys. +% \item |FT| is overwritten. +% \item For fields only the field flags |ReadOnly|, |Required|, |NoExport|, +% |Combo|, |Edit|, |MultiSelect|, |Sort|, |DoNotSpellCheck| and |CommitOnSelChange| +% make sense. The code will force some values (e.g. disable |Edit| if |Combo| is false). +% \end{itemize} +% +% +% \begin{function}{preset-choice} +% \begin{syntax} +% |preset-choice| = \Arg{key-val-list} +% \end{syntax} +% This allows to set default keys for a choice field. +% \end{function} +% +% \begin{function}{name,T} +% \begin{syntax} +% |name| = \meta{partial name}\\ +% |T| = \meta{partial name} +% \end{syntax} +% These keys set the partial name of the field. They both do the same +% thing, use the one you are more comfortable with. The value +% shouldn't contain a period, be not empty and sensibly consist of simple chars. +% Additionally the value is used to create the field ID. +% This means that choice field with the same partial name are annotations +% with the same field as parent. +% The field ID is then internal and can not be used to +% attach another annotation. +% For explicit control of the field ID use the |fieldID| key. +% \end{function} +% +% \begin{function}{value,values} +% \begin{syntax} +% |value| = \Arg{comma separated list of values} +% |values| = \Arg{comma separated list of values} +% \end{syntax} +% With these keys you set the export value names. \meta{comma separated list of values} should contain +% the values in the order as wanted. The values are passed through |\pdf_string_from_unicode:nnN| +% and can use unicode. +% \end{function} +% +% \begin{function}{display-values} +% \begin{syntax} +% |display-values| = \Arg{comma separated list of values} +% \end{syntax} +% With this key you set the display value names if they should be +% different from the export values. They should be given in the same order as the values. +% The values are passed through |\pdf_string_from_unicode:nnN| +% and can use unicode. +% \end{function} +% +% \begin{function}{default,default-values} +% \begin{syntax} +% |default| = \Arg{comma separated list of values} +% |default-values| = \Arg{comma separated list of values} +% \end{syntax} +% With this keys you set the values which are selected when the PDF is opened. +% The use of this keys is a bit dubious. It seems to work okay for combo fields, +% but not for list fields. According to the PDF reference the +% values should be the display values, but it is not clear if the PDF viewer +% really implement it that way or if the export value should be preferred. +% Depending on the values it could be needed to +% add also an |I| array to the field. +% \end{function} + +% \begin{function}{top-index} +% \begin{syntax} +% |top-index| = \Arg{integer} +% \end{syntax} +% With this key you set for a scrollable list field the number of the +% value shown at the top. The first value has number 1 (that is the default). +% I'm not sure if viewers handle this correctly, so the setting should be used with +% care. +% \end{function} + +% \begin{function}{fieldID} +% \begin{syntax} +% |fieldID| = \meta{field ID}\\ +% \end{syntax} +% \emph{For experts only!} +% This allows to give the radio field a specific ID. This is only useful +% in the context of a larger fieldset or if you want to attach another annotation +% to the field with \cs{pdffield_annot:n}. If used wrongly you can +% easily create invalid fieldset. It allows you to create to fields with the +% same partial name, but if you want to see both +% you need to ensure that their full names are +% different---for example by adding some parent fields. +% \end{function} +% +% \begin{function}{parent} +% \begin{syntax} +% |parent| = \meta{field ID}\\ +% \end{syntax} +% This is only needed if the field should be part +% of a larger fieldset. The value should be a field ID of a field created previously +% with \cs{pdffield_field:nn}. +% \end{function} +% +% +% \begin{function}{width,height,depth} +% \begin{syntax} +% |width| = \meta{dim expression}\\ +% |height| = \meta{dim expression}\\ +% |depth| = \meta{dim expression} +% \end{syntax} +% These keys allow to set the dimensions of the choice field. +% The value should be a dimension expression. By default +% |width| and |height| and |depth| are .... +% \end{function} +% +% \begin{function}{AP/N,appearance,AP/R,rollover-appearance,AP/D,down-appearance} +% \begin{syntax} +% |AP/N| = \meta{appearance name}\\ +% |appearance| = \meta{appearance name}\\ +% |AP/R| = \meta{appearance name}\\ +% |rollover-appearance| = \meta{appearance name}\\ +% |AP/D| = \meta{appearance name}\\ +% |down-appearance| = \meta{appearance name} +% \end{syntax} +% This adds appearances. \meta{appearance name} should be the name of an form Xobjects. +% The default normal appearance is a simple gray background, the same as with +% text fields. +% \end{function} +% +% The font are handled in a similar way as in textfield. Most of the remarks made there +% are true for choice fields too. +% +% \begin{function}{fontcolor} +% \begin{syntax} +% |fontcolor| = \meta{color expression} \verb"|" [\meta{model}]\Arg{values}\\ +% \end{syntax} +% This is sets the color of font in the textfield. Internally currently RGB is used. +% The colors used in +% \meta{color expression} must be known to the \pkg{l3color} commands. +% The initial color is black. It is a \emph{field} setting, that means instances +% share the color. +% \end{function} +% +% \begin{function}{fontsize} +% \begin{syntax} +% |fontsize| = \meta{dim expression} +% \end{syntax} +% This is sets the size of the font in the textfield. +% The default value is the current font size (\cs{f@size} in pt). +% It is a \emph{field} setting, that means instances +% share the size. +% \end{function} +% +% \begin{function}{font} +% \begin{syntax} +% |font| = \meta{symbolic font name} +% \end{syntax} +% This is sets the font in the textfield. See the discussion at the begin of +% the documentation about some background. The default value is |Helv| and this +% name is setup if you load hyperref and issue the \cs{Form} command. +% The default value is the current font size (\cs{f@size} in pt). +% It is a \emph{field} setting, that means instances +% share the font. +% \end{function} +% \subsection{Using with hyperref} +% +% hyperref combines radio button and choice field in one command. This makes it +% difficult to replicate the hyperref commands here. +% +% \end{documentation} +% +% \begin{implementation} +% % \DoNotIndex +% {\\ +% ,\bitset_clear:N +% ,\bitset_new:Nn +% ,\bitset_set_false:Nn +% ,\bitset_set_true:Nn +% ,\bitset_to_arabic:N +% ,\bitset_item:Nn +% ,\bool_new:N +% ,\box_dp:N +% ,\box_ht:N +% ,\clist_map_inline:nn +% ,\color_export:nnN +% ,\color_set:nn +% ,\color_set:nnn +% ,\color_select:n +% ,\cs_new_protected:Npn +% ,\cs_new_protected:cpn +% ,\cs_set_eq:NN +% ,\cs_gset_eq:cN +% ,\cs_set_protected:Npn +% ,\cs_generate_variant:Nn +% ,\cs_gset_eq:NN +% ,\c_space_tl +% ,\csname +% ,\dim_eval:n +% ,\dim_new:N +% ,\dim_to_decimal_in_bp:n +% ,\endcsname +% ,\exp_args:Ne +% ,\exp_args:Nc +% ,\fboxsep +% ,\fp_eval:n +% ,\f@size +% ,\group_begin: +% ,\group_end: +% ,\hbox_to_wd:nn +% ,\hfill +% ,\hook_gput_code:nnn +% ,\int_eval:n +% ,\int_compare:nNnT +% ,\int_compare:nNnTF +% ,\int_incr:N +% ,\int_new:N +% ,\int_use:N +% ,\int_zero:N +% ,\l_keys_choice_int +% ,\keys_define:nn +% ,\keys_set:nn +% ,\mode_leave_vertical: +% ,\msg_error:nnn +% ,\msg_error:nnnn +% ,\msg_new:nnn +% ,\msg_warning:nn +% ,\msg_warning:nnn +% ,\msg_warning:nnnnn +% ,\NeedsTeXFormat +% ,\normalsize +% ,\paperheight +% ,\paperwidth +% ,\pdf_name_from_unicode_e:n +% ,\pdf_object_if_exist:nTF +% ,\pdf_object_if_exist:nF +% ,\pdf_object_new:nn +% ,\pdf_object_ref:n +% ,\pdf_object_ref_last: +% ,\pdf_object_unnamed_write:nn +% ,\pdf_object_unnamed_write:nx +% ,\pdf_object_write:nx +% ,\pdf_object_write:nn +% ,\pdf_string_from_unicode:nnN +% ,\pdfannot_box_ref_last: +% ,\pdfannot_dict_put:nnn +% ,\pdfannot_dict_put:nnx +% ,\pdfdict_put:nnx +% ,\pdfannot_dict_remove:nn +% ,\pdfannot_widget_box:nnn +% ,\pdfdict_if_empty:nTF +% ,\pdfdict_get:nnN +% ,\pdfdict_new:n +% ,\pdfdict_put:nnn +% ,\pdfdict_remove:nn +% ,\pdfdict_use:n +% ,\pdfmanagement_add:nnn +% ,\pdfmeta_standard_verify:nTF +% ,\pdfxform_if_exist:nTF +% ,\pdfxform_new:nnn +% ,\pdfxform_ref:n +% ,\phantom +% ,\prg_do_nothing: +% ,\ProvidesExplPackage +% ,\quark_if_no_value:NT +% ,\raisebox +% ,\RequirePackage +% ,\rule +% ,\seq_gput_right:Nn +% ,\seq_gput_right:cV +% ,\seq_gput_left:cV +% ,\seq_if_in:cVF +% ,\seq_map_break: +% ,\seq_map_inline:Nn +% ,\seq_new:c +% ,\seq_use:cn +% ,\seq_if_exist:NTF +% ,\seq_new:N +% ,\seq_use:Nn +% ,\smash +% ,\str_if_empty:NTF +% ,\str_if_in:NnTF +% ,\str_if_eq:nVTF +% ,\str_new:N +% ,\strut +% ,\strutbox +% ,\tl_put_right:Nn +% ,\tl_if_empty:NTF +% ,\tl_if_empty:NT +% ,\tl_if_empty:NF +% ,\tl_put_left:Nn +% ,\tl_if_eq:NnF +% ,\tl_if_empty:nTF +% ,\tl_if_head_eq_charcode:nNTF +% ,\tl_new:N +% ,\tl_set:Nn +% ,\tl_to_str:n +% ,\use:c +% } +% \section{\pkg{l3pdffield-radiobutton} Implementation} +% \begin{macrocode} +%<*package> +%<@@=pdffield> +\RequirePackage{l3draw} +% \end{macrocode} +% \subsection{Variables} +% \begin{variable} +% { +% \l_@@_choice_values_seq +% ,\l_@@_choice_defaultvalues_seq +% ,\l_@@_choice_displayvalues_seq +% ,\l_@@_choice_opt_seq +% } +% variables to hold the value, the default value, and display variants. The opt +% set will be used to build the content of opt +% \begin{macrocode} +\seq_new:N \l_@@_choice_values_seq +\seq_new:N \l_@@_choice_defaultvalues_seq +\seq_new:N \l_@@_choice_displayvalues_seq +\seq_new:N \l_@@_choice_opt_seq +% \end{macrocode} +% \end{variable} +% +% \subsection{Appearances} +% (probably take from textfield ...) +% +%\subsection{Creating the field} +% A field should be created if the name doesn't exist yet +% \begin{macro}{\@@_choice_field:n} +% \begin{macrocode} +\cs_new_protected:Npn \@@_choice_field:n #1 %name + { + \pdf_object_if_exist:nF {@@/field/@@/choice/#1} + { +% \end{macrocode} +% We must at first build the Opt array. +% \begin{macrocode} + \seq_clear:N \l_@@_choice_opt_seq + \seq_map_indexed_inline:Nn \l_@@_choice_values_seq + { + \pdf_string_from_unicode:nnN{utf16/hex}{##2}\l_@@_tmpa_str + \tl_set:Nx \l_@@_tmpa_tl {\seq_item:Nn \l_@@_choice_displayvalues_seq {##1} } + \tl_if_empty:NTF \l_@@_tmpa_tl + { + \seq_put_right:NV \l_@@_choice_opt_seq \l_@@_tmpa_str + } + { + \exp_args:NnV + \pdf_string_from_unicode:nnN{utf16/hex}\l_@@_tmpa_tl\l_@@_tmpb_str + \seq_put_right:Nx \l_@@_choice_opt_seq + { [ \l_@@_tmpa_str\c_space_tl\l_@@_tmpb_str] } + } + } + \pdf_object_unnamed_write:nx {array}{\seq_use:Nn\l_@@_choice_opt_seq {~}} + \pdfdict_put:nnx { l_@@/field }{Opt} { \pdf_object_ref_last: } +% \end{macrocode} +% Now we handle the V value. If MultiSelect is set, we use the full +% displayvalues seq, if not only the first value. +% \begin{macrocode} + \int_compare:nNnTF {\bitset_item:Nn \l_@@_Ff_bitset {MultiSelect}} = {1} + { + \tl_clear:N \l_@@_tmpa_tl + \seq_map_inline:Nn \l_@@_choice_defaultvalues_seq + { + \pdf_string_from_unicode:nnN{utf16/hex}{##1}\l_@@_tmpa_str + \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpa_str + \pdfdict_put:nnx { l_@@/field }{V} { [ \l_@@_tmpa_tl ] } + } + } + { + \tl_set:Nx \l_@@_tmpa_tl {\seq_item:Nn \l_@@_choice_defaultvalues_seq {1} } + \exp_args:NnV + \pdf_string_from_unicode:nnN{utf16/hex}\l_@@_tmpa_tl\l_@@_tmpb_str + \pdfdict_put:nnx { l_@@/field }{V} { \l_@@_tmpb_str } + } +% \end{macrocode} +% now we create the field and set it as parent for the following annotation. +% \begin{macrocode} + \@@_field:n { @@/choice/#1 } + } + \keys_set:nn {pdffield}{parent=@@/choice/#1} + } +\cs_generate_variant:Nn \@@_choice_field:n {V} +% \end{macrocode} +% \end{macro} +% +% \subsection{Assembling the choice field} +% +% \begin{macro}{\@@_choice:n} +% The argument are key-val settings. +% At first we map the handlers. +% As default appearance we reuse the text appearance: a simple gray background. +% \begin{macrocode} +\cs_new_protected:Npn \@@_choice:n #1 + { + \group_begin: + \cs_set_eq:NN\@@_value_handler:n \@@_choice_value_handler:n + \cs_set_eq:NN\@@_default_handler:n \@@_choice_default_handler:n + \@@_textfield_default_appearance: +% \end{macrocode} +% Setting up the defaults. +% \begin{macrocode} + \keys_set:nn {pdffield} + { + fieldID= + ,name=choice + ,appearance = pdffield/textfield/default + ,width = 3cm + ,height = \normalbaselineskip + ,type=combo-edit + ,@@/preset/choice + ,#1 + ,FT= Ch + } + \@@_choice_set_type: + \keys_set:nn {pdffield} + { + ,DA= + { + \pdf_name_from_unicode_e:n{\l_@@_DA_fontname_tl} + \c_space_tl + \dim_to_decimal_in_bp:n{\l_@@_DA_fontsize_dim} + \c_space_tl + Tf + \c_space_tl + \l_@@_DA_fontcolor_tl + \c_space_tl + %\l_@@_text_DAextra_tl + } + } +% \end{macrocode} +% If the fieldID has not been set explicitly, we use the name/T key +% \begin{macrocode} + \tl_if_empty:NT\l_@@_fieldID_tl + { + \pdfdict_get:nnN {l_@@/field}{T}\l_@@_fieldID_tl + \tl_put_left:Nn \l_@@_fieldID_tl {@@/choice/} + } +% \end{macrocode} +% Now we build the field +% \begin{macrocode} + \@@_choice_field:V\l_@@_fieldID_tl +% \end{macrocode} +% And add the annotation. +% \begin{macrocode} + \@@_annot: + \group_end: + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Keys and handlers} +% Most keys are inherited simply the ones from the generic field and annot keys. +% We define a group key, as the name is better. +% The value key sets the export value. default the button which is checked on. +% At first the two handlers +% \begin{macro}{\@@_choice_value_handler:n,\@@_choice_default_handler:n,display-values} +% \begin{macrocode} +\cs_new_protected:Npn \@@_choice_value_handler:n #1 + { + \seq_set_from_clist:Nn \l_@@_choice_values_seq {#1} + } +\cs_new_protected:Npn \@@_choice_default_handler:n #1 + { + \seq_set_from_clist:Nn \l_@@_choice_defaultvalues_seq {#1} + } +\keys_define:nn{pdffield} + { + values .meta:n = {value={#1}} + ,default-values .meta:n = {default={#1}} + ,display-values .code:n = + { + \seq_set_from_clist:Nn \l_@@_choice_displayvalues_seq {#1} + } + ,top-index .code:n = + { + \pdfdict_put:nnx {l_@@/field}{TI}{\int_eval:n{#1-1}} + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{type} +% \begin{macrocode} +\cs_new_protected:Npn \@@_choice_set_type: {} + +\keys_define:nn { pdffield } + { + type .choice: + ,type / combo .code:n = + { + \cs_set_protected:Npn\@@_choice_set_type: + { + \keys_set:nn{pdffield}{setFf={Combo},unsetFf={Edit,DoNotSpellCheck}} + } + } + ,type / combo-edit .code:n = + { + \cs_set_protected:Npn\@@_choice_set_type: + { + \keys_set:nn{pdffield}{setFf={Combo,Edit}} + } + } + ,type / list .code:n = + { + \cs_set_protected:Npn\@@_choice_set_type: + { + \keys_set:nn{pdffield}{unsetFf={Combo,Edit,},unsetFf={Edit,DoNotSpellCheck}} + } + } + } +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@@_choice_appearance_handler:nnn} +% The handler for the appearances stores only the code +% as it must be executed rather late. +% \begin{macrocode} +\cs_new_protected:Npn \@@_choice_appearance_handler:nnn #1 #2 #3 %name, type, text + { + } + +% \end{macrocode} +% +% \end{macro} +% +% \subsection{User commands} +% \begin{macro}{\pdffield_choice:n} +% \begin{macrocode} +\cs_set_eq:NN \pdffield_choice:n \@@_choice:n +%</package> +% \end{macrocode} +% \end{macro} +%\end{implementation} +% \PrintIndex |