From 2faf2507ca4d1d6d153f4c2b4c4c78479d459f06 Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Tue, 15 Jun 2021 03:01:03 +0000
Subject: CTAN sync 202106150301

---
 .../l3pdffield-radiobutton.dtx                     | 835 +++++++++++++++++++++
 1 file changed, 835 insertions(+)
 create mode 100644 macros/latex/contrib/pdfmanagement-testphase/l3pdffield-radiobutton.dtx

(limited to 'macros/latex/contrib/pdfmanagement-testphase/l3pdffield-radiobutton.dtx')

diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-radiobutton.dtx b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-radiobutton.dtx
new file mode 100644
index 0000000000..69187ec765
--- /dev/null
+++ b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-radiobutton.dtx
@@ -0,0 +1,835 @@
+% \iffalse meta-comment
+%
+%% File: l3pdfpdffield-radiobutton.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,bearwear,tikzlings,tikzducks}
+\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}}
+% \ExplSyntaxOn
+% \box_new:N\l_pdffield_bear_box
+% \box_new:N\l_pdffield_hippo_box
+% \box_new:N\l_pdffield_duck_box
+% \hbox_set:Nn \l_pdffield_bear_box  {\tikz\bear\bearwear[shirt=red,body~deco={\node[font=\tiny\bfseries,white]~at~(beartummy){Yes};}];}
+% \hbox_set:Nn \l_pdffield_hippo_box {\vphantom{\tikz\bear;}\tikz\hippo;}
+% \hbox_set:Nn \l_pdffield_duck_box  {\vphantom{\tikz\bear;}\tikz\duck;}
+%
+%
+% \pdffield_appearance:nn {pdffield/bear/Yes}
+%  {
+%    \fbox{\box_use:N \l_pdffield_bear_box}
+%  }
+% \pdffield_appearance:nn {pdffield/bear/Off}
+%  {
+%    \fbox{\phantom{\box_use:N \l_pdffield_bear_box}}
+%  }
+% \pdffield_appearance:nn {pdffield/hippo/Yes}
+%  {
+%    \fbox{\box_use:N \l_pdffield_hippo_box}
+%  }
+% \pdffield_appearance:nn {pdffield/hippo/Off}
+%  {
+%    \fbox{\phantom{\box_use:N \l_pdffield_hippo_box}}
+%  }%
+% \pdffield_appearance:nn {pdffield/duck/Yes}
+%  {
+%    \fbox{\box_use:N \l_pdffield_duck_box}
+%  }
+% \pdffield_appearance:nn {pdffield/duck/Off}
+%  {
+%    \fbox{\phantom{\box_use:N \l_pdffield_duck_box}}
+%  }%
+% \ExplSyntaxOff
+% \title{^^A
+%   The \pkg{l3pdffield-radiobutton} module\\ Commands to create radio form 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-radiobutton} Introduction}
+% This is the documentation for radio buttons fields, for general information about form fields
+% check the documentation l3pdffield.
+%
+% \begin{center}
+%  Choose your favorite
+%
+%  \medskip
+% \ExplSyntaxOn
+% \begin{tabular}{ccc}
+% \pdffield_radio:n{name=A,value=Bär,default=B,appearance=pdffield/bear,width=\box_wd:N\l_pdffield_bear_box,height=\box_ht:N\l_pdffield_bear_box}&
+% \pdffield_radio:n{name=A,value=Sieglinde,appearance=pdffield/hippo,width=\box_wd:N\l_pdffield_hippo_box,height=\box_ht:N\l_pdffield_hippo_box}&
+% \pdffield_radio:n{name=A,value=Duck,appearance=pdffield/duck,width=\box_wd:N\l_pdffield_duck_box,height=\box_ht:N\l_pdffield_duck_box}\\[1ex]
+% \pdffield_radio:n{name=A,value=Bär}&
+% \pdffield_radio:n{name=A,value=Sieglinde}&
+% \pdffield_radio:n{name=A,value=Duck}
+% \end{tabular}
+% \ExplSyntaxOff
+% \end{center}
+%
+% Please keep in mind
+% \begin{itemize}
+% \item Not every PDF viewer supports radio buttons.
+% \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{Radio buttons}
+% Click me:
+% \ExplSyntaxOn
+%  ^^A \pdffield_radio:n{name=bear,appearance=pdffield/bear,width=23pt,height=30pt,depth=10pt}
+% \ExplSyntaxOff
+%
+% Radio buttons are similar to checkboxes and
+% they have like checkboxes two \enquote{states}:
+% checked and unchecked.
+%
+% The difference is that multiple checkboxes are either \enquote{clones} of each other
+% which  are checked and unchecked together,
+% or they are independent of each other.
+% Radio buttons on the other side build \emph{groups}
+% where checking one of the buttons unchecks all other buttons.
+% The elements of a such a radio button group are annotations of one field which
+% has a flag set which makes it into a radio button group.
+%
+% In a checkbox field the two states have the
+% fix names |/Yes| and |/Off|.
+%
+% \begin{center}
+%  \begin{tikzpicture}[level 2/.style={level distance=7mm},
+%  level 1/.style={sibling distance=25mm},
+%  level 2/.style={sibling distance=15mm}]
+%   \node[draw] {checkbox field}
+%           child {node[draw,dashed,align=left,font=\ttfamily]
+%             {\textrm{annotation}\\ /Yes\\
+%               /Off
+%             }}
+%           child {node[draw,dashed,align=left,font=\ttfamily]
+%             {\textrm{annotation}\\ /Yes\\
+%               /Off
+%             }}
+%   ;
+%   \end{tikzpicture}
+% \end{center}
+%
+% In radio buttons
+% the off state should still always have the name |/Off|\footnote{%
+% the PDF reference doesn't say anything about this, but various tests showed that
+% one better should stick to this name, with other names the buttons disappeared.}
+% but the on state should be a specific value for every button.
+% The field dictionary should then set
+% in the |/V| key as the value of one of the button.
+% This button is then set as selected and all the other are deselected when the
+% PDF is opened or reset.
+%
+% It is theoretically possible to control the start appearance state for every
+% button so e.g. all buttons could have the \enquote{selected} state when the PDF is opened.
+% But as soon as one button is clicked
+% you get one selected button and the other are unselected. You can't select or
+% deselect all buttons. The PDF reference mentions an flag |NoToggleToOff| but this
+% doesn't do anything, at least not in the PDF viewers I tried. For this
+% reason setting special start states is currently not supported: it complicates the code and the
+% input for no real gain.
+%
+%
+% The values of the individual buttons can be coded as annotation state names:
+%
+% \begin{center}
+%    \begin{tikzpicture}[level 2/.style={level distance=7mm},
+%  level 1/.style={sibling distance=25mm},
+%  level 2/.style={sibling distance=15mm}]
+%   \node[draw,align=left,font=\ttfamily] {\textrm{radio button field}\\/V /value1 }
+%           child {node[draw,dashed,align=left,font=\ttfamily]
+%             {\textrm{annotation}\\ /value0 \\
+%               /Off
+%             }}
+%           child {node[draw,dashed,align=left,font=\ttfamily]
+%             {\textrm{annotation}\\ /value1 \\
+%               /Off
+%             }}
+%           child {node[draw,dashed,align=left,font=\ttfamily]
+%             {\textrm{annotation}\\ /value2 \\
+%               /Off
+%             }}
+%   ;
+%   \end{tikzpicture}
+% \end{center}
+%
+% But it can be awkward to have to use the values also as names of appearances states, it
+% makes it for example difficult to use unicode for the value names, so there is another
+% option: One can set up an |/Opt| array which contains the values as strings,
+% and used \enquote{named numbers} as appearance state name: The numbers
+% |/0|, |/1| point then to the index position in the array.
+%
+% \begin{center}
+%  \begin{tikzpicture}[level 2/.style={level distance=7mm},
+%  level 1/.style={sibling distance=25mm},
+%  level 2/.style={sibling distance=15mm}]
+%   \node[draw,align=left,font=\ttfamily] {\textrm{radio button field}\\
+%           /Opt [(value0) (value1) (value2)]
+%           /V /0 }
+%           child {node[draw,dashed,align=left,font=\ttfamily]
+%             {\textrm{annotation}\\ /0 \\
+%               /Off
+%             }}
+%           child {node[draw,dashed,align=left,font=\ttfamily]
+%             {\textrm{annotation}\\ /1 \\
+%               /Off
+%             }}
+%           child {node[draw,dashed,align=left,font=\ttfamily]
+%             {\textrm{annotation}\\ /2 \\
+%               /Off
+%             }}
+%   ;
+%   \end{tikzpicture}
+% \end{center}
+%
+% This method is clearly more flexible, and so it is used in this module.
+%
+% As radio buttons build a group of buttons, there is more interaction going on,
+% and more values have to be set. Also the first command, which initializes the field,
+% has to set the default value of the group.
+%
+% This means a typical setup should do something like this
+%
+% \begin{verbatim}
+% \pdffield_radio:n
+%   {
+%     group   = A,         % required, can also be given as name=A or T=A
+%     value   = button1,   % required,  on-state of this button
+%     default = button4    % default of the group,
+%                          % if not given choice (button1) is used
+%                          % should refer to an existing button!
+%                          % It will set the V and the DV key
+%                          % button4 will be checked
+%   }
+% \pdffield_radio:n
+%   {
+%     group   = A,        % required, can also be given as name=A or T=A
+%     value   = button2   % required,  export value of this button
+%   }
+% \pdffield_radio:n
+%   {
+%     group   = A,        % required, can also be given as name=A or T=A
+%     value   = button3,  % required,  choice/export value of this button
+%   }
+% \pdffield_radio:n
+%   {
+%     group   = A,        % required, can also be given as name=A or T=A
+%     value   = button4   % required,  choice/export value of this button
+%   }
+% \end{verbatim}
+%
+%
+% If two radio field annotations use the same |value| they are selected and
+% unselected together, like checkboxes with the same |/Yes| state. This can be used
+% to build radio groups which works \enquote{in unison}. The flag |RadiosInUnison|
+% is neither needed for this (but doesn't harm either) nor
+% does it change the behaviour, at least again not in the PDF viewers I tried.
+%
+%
+% \bigskip
+% \subsection{Commands}
+% \begin{function}{\pdffield_radio:n}
+% \begin{syntax}
+%  \cs{pdffield_radio:n}\Arg{key val list}
+% \end{syntax}
+% This creates a radio button to check and uncheck.
+% The list of allowed keys is described below.
+% The \meta{key val list} should at least set the group name,
+% without it the default group
+% |radio| is used. Radiobuttons with the same
+% group name belong to the same field and if checked, the others are unchecked.
+% The default appearance
+% is a circle frame with a black bullet in it for the checked case.
+% The default appearance is setup at the first use. Its geometry is quadratic.
+%
+% The first radio button setups the field and should also set the button which
+% should be shown as selected when the PDF is opened.
+% \end{function}
+%
+%
+% \subsection{Keys}
+%
+% The new radio 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 more radio specific
+% behaviour, other keys have other defaults than with the basic commands.
+% Additionally there
+% are a small number of keys specific to a radio button.
+% |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 radio buttons only the field flags  |ReadOnly|, |Required|, |NoExport|,
+%  |NoToggleToOff| and |RadiosInUnison| make sense. The last two are as mentioned
+%  above probably useless.
+%  |Radio| is set automatically automatically by the code
+% as this is required for a radio button set.
+%  \end{itemize}
+%
+%
+% \begin{function}{preset-radiobutton}
+%  \begin{syntax}
+%   |preset-radiobutton| = \Arg{key-val-list}
+%  \end{syntax}
+% This allows to set default keys for a radio button.
+% \end{function}
+%
+% \begin{function}{group,name,T}
+%  \begin{syntax}
+%   |group| = \meta{partial name}\\
+%   |name| = \meta{partial name}\\
+%   |T| = \meta{partial name}
+%  \end{syntax}
+% These keys set the partial name of the field. They all 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 radio buttons with the same partial name are annotations
+% with the same field as parent and so build a radio button group.
+% 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}
+%  \begin{syntax}
+%   |value| = \meta{string}
+%  \end{syntax}
+%  With this key you set the export value name for the individual buttons.
+%  Every button should have a value.
+%  buttons with the same value are checked in unison. The value can use unicode.
+%  \end{function}
+%
+%  \begin{function}{default}
+%  \begin{syntax}
+%   |default| = \meta{string}
+%  \end{syntax}
+%  With this key you set the button which is checked when the PDF is opened.
+%  The key must be used in the command of the first button. If it is missing
+%  the value of the first button is used as default.
+%  \meta{string} should be identical to a |value| of one of the buttons of the group.
+%  This is not checked, buttons can be created on various pages, so it would
+%  require a label/ref system to keep track of the names.
+%  \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 radio button.
+% The value should be a dimension expression. By default
+% |width| and |height| use \cs{normalbaselineskip}, the |depth| is zero.
+% \end{function}
+%
+% \begin{function}{AP/N,appearance,AP/R,rollover-appearance,AP/D,down-appearance}
+%  \begin{syntax}
+%   |AP/N| = \meta{partial appearance name}\\
+%   |appearance| = \meta{partial appearance name}\\
+%   |AP/R| = \meta{partial appearance name}\\
+%   |rollover-appearance| = \meta{partial appearance name}\\
+%   |AP/D| = \meta{partial appearance name}\\
+%   |down-appearance| = \meta{partial appearance name}
+%  \end{syntax}
+% This keys sets the normal appearance, the rollover appearance (when the
+% mouse hovers over the checkbox) and the down appearance (when the
+% mouse clicks). They take as value a
+% \meta{partial appearance name} and expects that \emph{two} form Xobjects
+% \meta{partial appearance name}|/Yes| and \meta{partial appearance name}|/Off|
+% has been created. The initial value is |pdffield/radio/default|
+% for the normal appearance and shows a button.
+% The down appearance enlarges the middle button a bit to give a visual feed back.
+% \end{function}
+%
+% \subsection{Using with hyperref}
+% Radio buttons in hyperref are created with \cs{ChoiceMenu} command, and
+% they also print a label. choices are actually a different field type and
+% so created with different commands. It is not quite clear yet,
+% how this could be mapped.
+%
+%
+% \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_@@_radio_value_tl
+%     ,\l_@@_radio_default_tl
+%     ,\l_@@_radio_value_num_int
+%     ,\l_@@_radio_appearance_code_tl
+%  }
+% variables to hold the value, its index numbers and the default value.
+% radio buttons can setup the appearance only after the value is known,
+% so the code is stored and executed later.
+%    \begin{macrocode}
+\tl_new:N  \l_@@_radio_value_tl
+\tl_new:N  \l_@@_radio_default_tl
+\int_new:N \l_@@_radio_value_num_int
+\tl_new:N  \l_@@_radio_appearance_code_tl
+%    \end{macrocode}
+% \end{variable}
+%
+% \subsection{Appearances}
+% The default appearances are a circle with button in it.
+% Every appearance should have two versions and follow the naming
+% module/\meta{name}/Yes and module/\meta{name}/Off.
+%
+%  \begin{macro}
+%   {
+%     \@@_radio_default_appearances:,
+%     pdffield/radio/default/Yes,
+%     pdffield/radio/default/Off,
+%     pdffield/radio/defaultdown/Yes,
+%     pdffield/radio/defaultdown/Off
+%   }
+%  This defines the standard appearances. They are setup at the first
+%  use of a radiobutton.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_radio_default_appearances:
+  {
+    \pdffield_appearance:nn {pdffield/radio/default/Yes}
+       {
+         \normalsize
+         \draw_begin:
+         \draw_path_circle:nn {0pt,0pt}{0.5\normalbaselineskip}
+         \draw_path_use_clear:n { stroke }
+         \draw_path_circle:nn {0pt,0pt}{0.2\normalbaselineskip}
+         \draw_path_use_clear:n { fill }
+         \draw_end:
+       }
+     \pdffield_appearance:nn {pdffield/radio/default/Off}
+       {
+         \normalsize
+         \draw_begin:
+         \draw_path_circle:nn {0pt,0pt}{0.5\normalbaselineskip}
+         \draw_path_use_clear:n { stroke }
+         \draw_end:
+      }
+
+    \pdffield_appearance:nn {pdffield/radio/defaultdown/Yes}
+       {
+         \normalsize
+         \draw_begin:
+         \draw_path_circle:nn {0pt,0pt}{0.5\normalbaselineskip}
+         \draw_path_use_clear:n { stroke }
+         \draw_path_circle:nn {0pt,0pt}{0.25\normalbaselineskip}
+         \draw_path_use_clear:n { fill }
+         \draw_end:
+       }
+     \pdffield_appearance:nn {pdffield/radio/defaultdown/Off}
+       {
+         \normalsize
+         \draw_begin:
+         \draw_path_circle:nn {0pt,0pt}{0.5\normalbaselineskip}
+         \draw_path_use_clear:n { stroke }
+         \draw_path_circle:nn {0pt,0pt}{0.25\normalbaselineskip}
+         \draw_path_use_clear:n { fill }
+         \draw_end:
+      }
+    \cs_gset_eq:NN \@@_radio_default_appearances: \prg_do_nothing:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%\subsection{Creating the field}
+% A field should be created if the name doesn't exist yet
+%  \begin{macro}{\@@_radio_field:n}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_radio_field:n #1 %name
+  {
+    \pdf_object_if_exist:nF {@@/field/@@/radio/#1}
+      {
+%    \end{macrocode}
+% We need an object and a seq for the Opt array.
+% The object is written at the end of the document.
+%    \begin{macrocode}
+        \pdf_object_new:nn {@@/field/@@/radio-Opt/#1}{array}
+        \pdfdict_put:nnx { l_@@/field }{Opt} { \pdf_object_ref:n {@@/field/@@/radio-Opt/#1} }
+        \seq_new:c { g_@@_radio_opt_#1_seq }
+        \hook_gput_code:nnn {shipout/lastpage}{pdffield/radio}
+          {
+            \pdf_object_write:nx
+              {@@/field/@@/radio-Opt/#1}
+              {\seq_use:cn {g_@@_radio_opt_#1_seq}{~}}
+          }
+%    \end{macrocode}
+% The default value is always the first in the array.
+% If a default has been set, it is added to the left
+% of the seq.
+%    \begin{macrocode}
+        \tl_if_eq:NnF \l_@@_radio_default_tl{()}
+         {
+           \seq_gput_left:cV { g_@@_radio_opt_#1_seq }\l_@@_radio_default_tl
+         }
+        \pdfdict_put:nnx { l_@@/field }{V}  { /0 }
+        \pdfdict_put:nnx { l_@@/field }{DV} { /0 }
+%    \end{macrocode}
+% now we create the field and set it as parent for the following annotation.
+%    \begin{macrocode}
+        \@@_field:n { @@/radio/#1 }
+      }
+    \keys_set:nn {pdffield}{parent=@@/radio/#1}
+  }
+\cs_generate_variant:Nn \@@_radio_field:n {V}
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Assembling the radio}
+%
+% \begin{macro}{\@@_radio:n}
+% The argument are key-val settings.
+% At first we map the handlers. To setup the appearance we need the
+% Opt array, so the appearance handler only stores the code.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_radio:n #1
+  {
+    \group_begin:
+    \cs_set_eq:NN\@@_appearance_handler:nnn \@@_radio_appearance_handler:nnn
+    \cs_set_eq:NN\@@_value_handler:n      \@@_radio_value_handler:n
+    \cs_set_eq:NN\@@_default_handler:n    \@@_radio_default_handler:n
+%    \end{macrocode}
+% Setting up the defaults.
+%   \begin{macrocode}
+    \tl_set:Nn\l_@@_radio_appearance_code_tl{}
+    \keys_set:nn {pdffield}
+      {
+         fieldID=
+        ,name=radio
+        ,width  = \normalbaselineskip
+        ,height = \normalbaselineskip
+        ,@@/preset/radiobutton
+        ,#1
+        ,unsetFf={Pushbutton}
+        ,setFf={Radio}
+        ,FT= Btn
+      }
+%    \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 {@@/radio/}
+      }
+%    \end{macrocode}
+% Now we build the field
+%    \begin{macrocode}
+    \@@_radio_field:V\l_@@_fieldID_tl
+%    \end{macrocode}
+%  Retrieve the number for the label
+%    \begin{macrocode}
+    \seq_if_in:cVF { g_@@_radio_opt_ \l_@@_fieldID_tl _seq }\l_@@_radio_value_tl
+      {
+        \seq_gput_right:cV { g_@@_radio_opt_ \l_@@_fieldID_tl _seq }\l_@@_radio_value_tl
+      }
+    \int_zero:N \l_@@_radio_value_num_int
+    \exp_args:Nc
+    \seq_map_inline:Nn { g_@@_radio_opt_ \l_@@_fieldID_tl _seq }
+     {
+       \str_if_eq:nVTF { ##1 } \l_@@_radio_value_tl
+        {
+          \seq_map_break:
+        }
+        {
+          \int_incr:N \l_@@_radio_value_num_int
+        }
+     }
+%    \end{macrocode}
+% Annotations with the default value are set to on, the rest to off
+%    \begin{macrocode}
+   \int_compare:nNnTF { \l_@@_radio_value_num_int } = 0
+     { \pdfannot_dict_put:nnx {widget}{AS}{/0} }
+     { \pdfannot_dict_put:nnx {widget}{AS}{/Off} }
+%    \end{macrocode}
+% Now we set the appearances, if no key has been use we take the default.
+%    \begin{macrocode}
+    \tl_if_empty:NT\l_@@_radio_appearance_code_tl
+      {
+        \@@_radio_default_appearances:
+        \keys_set:nn {pdffield}
+          {
+            appearance      = pdffield/radio/default,
+            down-appearance = pdffield/radio/defaultdown,
+          }
+      }
+    \l_@@_radio_appearance_code_tl
+    \@@_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}{\@@_radio_value_handler:n,\@@_radio_default_handler:n}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_radio_value_handler:n #1
+  {
+    \pdf_string_from_unicode:nnN {utf8/string}{#1}\l_@@_radio_value_tl
+  }
+\cs_new_protected:Npn \@@_radio_default_handler:n #1
+  {
+    \pdf_string_from_unicode:nnN {utf8/string}{#1}\l_@@_radio_default_tl
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{group}
+%    \begin{macrocode}
+\keys_define:nn { pdffield }
+ {
+    group .meta:n = {T=#1}
+ }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_radio_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 \@@_radio_appearance_handler:nnn #1 #2 #3 %name, type, text
+  {
+    \tl_put_right:Nn \l_@@_radio_appearance_code_tl
+      {
+         \pdfxform_if_exist:nTF {  #1 / Yes }
+           {
+             \pdf_object_unnamed_write:nx
+               {dict}
+               {
+                  /\int_use:N \l_@@_radio_value_num_int
+                   \c_space_tl   \pdfxform_ref:n  { #1/Yes}
+                  /Off ~ \pdfxform_ref:n { #1/Off}
+               }
+            \pdfannot_dict_put:nnx {widget/AP}{#2}{\pdf_object_ref_last:}
+           }
+           {
+              \msg_error:nnnn{pdffield}{appearance-missing}{#1}{#3}
+           }
+       }
+   }
+
+%    \end{macrocode}
+%
+% \end{macro}
+%
+% \subsection{User commands}
+% \begin{macro}{\pdffield_radio:n}
+%    \begin{macrocode}
+\cs_set_eq:NN \pdffield_radio:n \@@_radio:n
+%</package>
+%    \end{macrocode}
+% \end{macro}
+%\end{implementation}
+% \PrintIndex
-- 
cgit v1.2.3

