From 2faf2507ca4d1d6d153f4c2b4c4c78479d459f06 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Tue, 15 Jun 2021 03:01:03 +0000 Subject: CTAN sync 202106150301 --- .../contrib/pdfmanagement-testphase/CHANGELOG.md | 35 +- .../contrib/pdfmanagement-testphase/README.md | 2 +- .../contrib/pdfmanagement-testphase/color-ltx.sty | 2 +- .../pdfmanagement-testphase/hyperref-generic.dtx | 27 +- .../pdfmanagement-testphase/hyperref-generic.pdf | Bin 947436 -> 947285 bytes .../hyperxmp-patches-tmp-ltx.sty | 2 +- .../l3backend-testphase.dtx | 14 +- .../l3backend-testphase.pdf | Bin 588344 -> 588643 bytes .../contrib/pdfmanagement-testphase/l3pdfannot.dtx | 4 +- .../contrib/pdfmanagement-testphase/l3pdfannot.pdf | Bin 573518 -> 573830 bytes .../contrib/pdfmanagement-testphase/l3pdfdict.dtx | 4 +- .../contrib/pdfmanagement-testphase/l3pdfdict.pdf | Bin 526914 -> 527359 bytes .../pdfmanagement-testphase/l3pdffield-action.dtx | 813 ++++++++++++++++++++ .../pdfmanagement-testphase/l3pdffield-action.pdf | Bin 0 -> 547960 bytes .../l3pdffield-checkbox.dtx | 187 ++++- .../l3pdffield-checkbox.pdf | Bin 438103 -> 530998 bytes .../pdfmanagement-testphase/l3pdffield-choice.dtx | 672 +++++++++++++++++ .../pdfmanagement-testphase/l3pdffield-choice.pdf | Bin 0 -> 534214 bytes .../l3pdffield-pushbutton.dtx | 765 +++++++++++++++++++ .../l3pdffield-pushbutton.pdf | Bin 0 -> 526289 bytes .../l3pdffield-radiobutton.dtx | 835 +++++++++++++++++++++ .../l3pdffield-radiobutton.pdf | Bin 296047 -> 576391 bytes .../l3pdffield-textfield.dtx | 215 +++++- .../l3pdffield-textfield.pdf | Bin 419934 -> 505625 bytes .../contrib/pdfmanagement-testphase/l3pdffield.dtx | 722 +++++++++++++++--- .../contrib/pdfmanagement-testphase/l3pdffield.pdf | Bin 619765 -> 739350 bytes .../contrib/pdfmanagement-testphase/l3pdffile.dtx | 36 +- .../contrib/pdfmanagement-testphase/l3pdffile.pdf | Bin 551626 -> 553291 bytes .../pdfmanagement-testphase/l3pdfmanagement.dtx | 11 +- .../pdfmanagement-testphase/l3pdfmanagement.pdf | Bin 658596 -> 659120 bytes .../contrib/pdfmanagement-testphase/l3pdfmeta.dtx | 43 +- .../contrib/pdfmanagement-testphase/l3pdfmeta.pdf | Bin 661637 -> 663941 bytes .../contrib/pdfmanagement-testphase/l3pdftools.dtx | 5 +- .../contrib/pdfmanagement-testphase/l3pdftools.pdf | Bin 517767 -> 518384 bytes .../contrib/pdfmanagement-testphase/l3pdfxform.dtx | 4 +- .../contrib/pdfmanagement-testphase/l3pdfxform.pdf | Bin 435558 -> 436061 bytes .../contrib/pdfmanagement-testphase/ltdocinit.dtx | 17 +- .../contrib/pdfmanagement-testphase/ltdocinit.pdf | Bin 552201 -> 553013 bytes .../pdfmanagement-testphase/pdflscape-ltx.sty | 4 +- .../pdfmanagement-firstaid.dtx | 4 +- .../pdfmanagement-firstaid.pdf | Bin 421911 -> 422418 bytes .../pdfmanagement-testphase.dtx | 6 +- .../pdfmanagement-testphase.ins | 4 + .../pdfmanagement-testphase.pdf | Bin 446163 -> 446685 bytes .../pdfmanagement-testphase/transparent-ltx.sty | 2 +- .../xcolor-patches-tmp-ltx.sty | 2 +- 46 files changed, 4227 insertions(+), 210 deletions(-) create mode 100644 macros/latex/contrib/pdfmanagement-testphase/l3pdffield-action.dtx create mode 100644 macros/latex/contrib/pdfmanagement-testphase/l3pdffield-action.pdf create mode 100644 macros/latex/contrib/pdfmanagement-testphase/l3pdffield-choice.dtx create mode 100644 macros/latex/contrib/pdfmanagement-testphase/l3pdffield-choice.pdf create mode 100644 macros/latex/contrib/pdfmanagement-testphase/l3pdffield-pushbutton.dtx create mode 100644 macros/latex/contrib/pdfmanagement-testphase/l3pdffield-pushbutton.pdf create mode 100644 macros/latex/contrib/pdfmanagement-testphase/l3pdffield-radiobutton.dtx (limited to 'macros/latex/contrib/pdfmanagement-testphase') diff --git a/macros/latex/contrib/pdfmanagement-testphase/CHANGELOG.md b/macros/latex/contrib/pdfmanagement-testphase/CHANGELOG.md index d114f50eed..9d7e75843d 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/CHANGELOG.md +++ b/macros/latex/contrib/pdfmanagement-testphase/CHANGELOG.md @@ -5,14 +5,41 @@ first release 0.95a, 2021-02-23 will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), this project uses date-based 'snapshot' version identifiers. -## [2021-05-14 +## [2021-06-14] +### Added + - l3pdffile: \pdffile_filespec:nnn to create a filespec dictionary + - l3pdffield: sortkey and code for calculate actions + - l3pdffield-radiobutton, a module for radiobuttons + - l3pdffield-pushbutton, a module for pushbuttons + - l3pdffield-choice, a module for choice fields + - l3pdffield-action, a module for reset/submit/import actions + - l3pdffield: \pdffield_annot_ref_last:, needed for tagging in OBJR object. + - \pdffile_filespec:nnn to create a filespec dictionary + - l3pdfmeta, ltdocinit: support for pdf A-2u and A-3u + - l3pdffield: tagging support for form fields + +### Fixed + - l3pdftools: utf8/URI didn't handle "?" + - l3pdffield: encoding of value in l3pdffield-textfield + - l3pdffield: encoding of value of TM and TU key + - utf8/URI in l3pdftools didn't handle ? + - option handling of pdflscape-ltx + - distiller failed due to empty /PAGES + - small bugs in the hyperref driver + +### Changed + - l3pdffield: handling of ECMAscript in /AA keys + - no longer force unicode in the generic hyperref driver as + it is the default where sensible anyway and clashes with platex. + +## [2021-05-14] ### Fixed - xcolor patch for [ps] type used in pstricks - value of citecolor wasn't expanded (errored with tcolorbox) - \url, \href, \hrefurl, \hrefrun and \hrefpdf leaves now vmode - - handling of pdfauthor, pdftitle and pdfsubject in hyperxmp patch - -### Changes + - handling of pdfauthor, pdftitle and pdfsubject in hyperxmp patch + +### Changed - the module for formfield and checkboxes has been in part rewritten to better fit to the new module for textfield. Keys and documentation has been extended. diff --git a/macros/latex/contrib/pdfmanagement-testphase/README.md b/macros/latex/contrib/pdfmanagement-testphase/README.md index 49840245c6..8f1a3ff674 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/README.md +++ b/macros/latex/contrib/pdfmanagement-testphase/README.md @@ -1,6 +1,6 @@ # LaTeX PDF management testphase bundle -Version: 0.95d, 2021-05-14 +Version: 0.95e, 2021-06-14 This package is used during a test phase to load the new PDF management code of LaTeX. diff --git a/macros/latex/contrib/pdfmanagement-testphase/color-ltx.sty b/macros/latex/contrib/pdfmanagement-testphase/color-ltx.sty index d8a6c9c408..e2a9e0059d 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/color-ltx.sty +++ b/macros/latex/contrib/pdfmanagement-testphase/color-ltx.sty @@ -22,7 +22,7 @@ %% This file has the LPPL maintenance status "maintained". %% \NeedsTeXFormat{LaTeX2e}[1995/12/01] -\ProvidesPackage{color-ltx}[2021-05-14 v0.95d +\ProvidesPackage{color-ltx}[2021-06-14 v0.95e Standard LaTeX Color (patched for l3color, part of pdfmanagement-testphase, original version 2021/03/07 v1.2e) (DPC)] \edef\Gin@codes{% \catcode`\noexpand\^^A\the\catcode`\^^A\relax diff --git a/macros/latex/contrib/pdfmanagement-testphase/hyperref-generic.dtx b/macros/latex/contrib/pdfmanagement-testphase/hyperref-generic.dtx index 30266d866c..c120f0060e 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/hyperref-generic.dtx +++ b/macros/latex/contrib/pdfmanagement-testphase/hyperref-generic.dtx @@ -86,7 +86,7 @@ % }^^A % } % -% \date{Version 0.95d, released 2021-05-14} +% \date{Version 0.95e, released 2021-06-14} % % \maketitle % \begin{documentation} @@ -922,7 +922,7 @@ %<@@=hyp> % \end{macrocode} % \begin{macrocode} -\ProvidesFile{hgeneric-testphase.def}[2021-05-14 v0.95d % +\ProvidesFile{hgeneric-testphase.def}[2021-06-14 v0.95e % generic Hyperref driver for the LaTeX PDF management testphase bundle] \RequirePackage{etoolbox} %why? @@ -1124,14 +1124,6 @@ \def\Hy@numberline#1{#1\c_space_tl} %needed by bookmark % \end{macrocode} % -% We force unicode as option. As bookmarks are still using \cs{pdfstringdef} -% we also need to load puenc.def. -% \begin{macrocode} -\HyPsd@LoadUnicode -\Hy@unicodetrue -\let\HyPsd@pdfencoding\HyPsd@pdfencoding@unicode -\Hy@DisableOption{unicode} -% \end{macrocode} % The pdfversion should be set in \cs{DeclareDocumentMetadata} but we must % copy it to the \pkg{hyperref} command: % \begin{macrocode} @@ -1214,7 +1206,7 @@ ,run-parameter .tl_set:N = \l_@@_href_run_parameter_tl ,nextactionraw .code:n = { %perhaps some safety match later, see hyperref code - \tl_if_empty:nTF + \tl_if_empty:nTF {#1} { \pdfdict_remove:nn{l_hyp/annot/A}{Next} } @@ -3335,7 +3327,7 @@ } ,pdfpagescrop .code:n = { - \tl_if_empty:nTF %or blank? + \tl_if_empty:nTF {#1} %or blank? { \pdfmanagement_remove:nn {Pages} { CropBox } } @@ -3962,6 +3954,16 @@ #1 .code:n= { \@@_store_metadata:nn {#1}{##1}} } } + +\str_if_eq:eeT {A}{\pdfmeta_standard_item:n{type}} + { + \exp_args:Nnx + \keys_set:nn {hyp / setup} + { + ,pdfapart = \pdfmeta_standard_item:n {level} + ,pdfaconformance = \pdfmeta_standard_item:n {conformance} + } + } % \end{macrocode} % % \subsection{Transitions} @@ -4219,6 +4221,7 @@ \seq_sort:Nn \l_@@_tmpa_seq { \int_compare:nNnTF { \pdf@strcmp{##1}{##2} } > { 0 } + %\str_compare:nNnTF {##1} > {##2} { \sort_return_swapped: } { \sort_return_same: } } diff --git a/macros/latex/contrib/pdfmanagement-testphase/hyperref-generic.pdf b/macros/latex/contrib/pdfmanagement-testphase/hyperref-generic.pdf index fb13e4b8e6..f8f62974fe 100644 Binary files a/macros/latex/contrib/pdfmanagement-testphase/hyperref-generic.pdf and b/macros/latex/contrib/pdfmanagement-testphase/hyperref-generic.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/hyperxmp-patches-tmp-ltx.sty b/macros/latex/contrib/pdfmanagement-testphase/hyperxmp-patches-tmp-ltx.sty index ab8723947e..b6c5de36a3 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/hyperxmp-patches-tmp-ltx.sty +++ b/macros/latex/contrib/pdfmanagement-testphase/hyperxmp-patches-tmp-ltx.sty @@ -19,7 +19,7 @@ % % for those people who are interested. \NeedsTeXFormat{LaTeX2e}[2020/10/01] -\ProvidesExplPackage{hyperxmp-patches-tmp-ltx}{2021-05-14}{0.95d} +\ProvidesExplPackage{hyperxmp-patches-tmp-ltx}{2021-06-14}{0.95e} {Store hyperref metadata in XMP format / temporay patches to test pdfresource management ... UF} \cs_if_exist:NT \pdfmanagement_add:nnn diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3backend-testphase.dtx b/macros/latex/contrib/pdfmanagement-testphase/l3backend-testphase.dtx index 497491f3b7..4ef756feb4 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/l3backend-testphase.dtx +++ b/macros/latex/contrib/pdfmanagement-testphase/l3backend-testphase.dtx @@ -45,7 +45,7 @@ % }^^A % } % -% \date{Version 0.95d, released 2021-05-14} +% \date{Version 0.95e, released 2021-06-14} % % \maketitle % @@ -56,27 +56,27 @@ % \begin{macrocode} %\ProvidesExplFile %<*dvipdfmx> - {l3backend-testphase-dvipdfmx.def}{2021-05-14}{} + {l3backend-testphase-dvipdfmx.def}{2021-06-14}{} {LaTeX~PDF~management~testphase~bundle~backend~support: dvipdfmx} % %<*dvips> - {l3backend-testphase-dvips.def}{2021-05-14}{} + {l3backend-testphase-dvips.def}{2021-06-14}{} {LaTeX~PDF~management~testphase~bundle~backend~support: dvips} % %<*dvisvgm> - {l3backend-testphase-dvisvgm.def}{2021-05-14}{} + {l3backend-testphase-dvisvgm.def}{2021-06-14}{} {LaTeX~PDF~management~testphase~bundle~backend~support: dvisvgm} % %<*luatex> - {l3backend-testphase-luatex.def}{2021-05-14}{} + {l3backend-testphase-luatex.def}{2021-06-14}{} {LaTeX~PDF~management~testphase~bundle~backend~support: PDF output (LuaTeX)} % %<*pdftex> - {l3backend-testphase-pdftex.def}{2021-05-14}{} + {l3backend-testphase-pdftex.def}{2021-06-14}{} {LaTeX~PDF~management~testphase~bundle~backend~support: PDF output (pdfTeX)} % %<*xdvipdfmx> - {l3backend-testphase-xetex.def}{2021-05-14}{} + {l3backend-testphase-xetex.def}{2021-06-14}{} {LaTeX~PDF~management~testphase~bundle~backend~support: XeTeX} % % \end{macrocode} diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3backend-testphase.pdf b/macros/latex/contrib/pdfmanagement-testphase/l3backend-testphase.pdf index 6e8a0d0155..b2d8378135 100644 Binary files a/macros/latex/contrib/pdfmanagement-testphase/l3backend-testphase.pdf and b/macros/latex/contrib/pdfmanagement-testphase/l3backend-testphase.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdfannot.dtx b/macros/latex/contrib/pdfmanagement-testphase/l3pdfannot.dtx index c8eddc0806..17cb4db002 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/l3pdfannot.dtx +++ b/macros/latex/contrib/pdfmanagement-testphase/l3pdfannot.dtx @@ -52,7 +52,7 @@ % }^^A % } % -% \date{Version 0.95d, released 2021-05-14} +% \date{Version 0.95e, released 2021-06-14} % % \maketitle % \begin{documentation} @@ -397,7 +397,7 @@ % \begin{macrocode} %<@@=pdfannot> %<*header> -\ProvidesExplPackage{l3pdfannot}{2021-05-14}{0.95d} +\ProvidesExplPackage{l3pdfannot}{2021-06-14}{0.95e} {PDF-annotations} \RequirePackage{l3pdfdict} % diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdfannot.pdf b/macros/latex/contrib/pdfmanagement-testphase/l3pdfannot.pdf index 8025552014..ccd2853d25 100644 Binary files a/macros/latex/contrib/pdfmanagement-testphase/l3pdfannot.pdf and b/macros/latex/contrib/pdfmanagement-testphase/l3pdfannot.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdfdict.dtx b/macros/latex/contrib/pdfmanagement-testphase/l3pdfdict.dtx index b23ff4508f..2c30250932 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/l3pdfdict.dtx +++ b/macros/latex/contrib/pdfmanagement-testphase/l3pdfdict.dtx @@ -53,7 +53,7 @@ % }^^A % } % -% \date{Version 0.95d, released 2021-05-14} +% \date{Version 0.95e, released 2021-06-14} % % \maketitle % \begin{documentation} @@ -212,7 +212,7 @@ % \begin{macrocode} %<@@=pdfdict> %<*header> -\ProvidesExplPackage{l3pdfdict}{2021-05-14}{0.95d} +\ProvidesExplPackage{l3pdfdict}{2021-06-14}{0.95e} {Tools for PDF dictionaries (LaTeX PDF management testphase bundle)} % % \end{macrocode} diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdfdict.pdf b/macros/latex/contrib/pdfmanagement-testphase/l3pdfdict.pdf index bb3eb95d68..d9633f9f28 100644 Binary files a/macros/latex/contrib/pdfmanagement-testphase/l3pdfdict.pdf and b/macros/latex/contrib/pdfmanagement-testphase/l3pdfdict.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-action.dtx b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-action.dtx new file mode 100644 index 0000000000..74362cc9a8 --- /dev/null +++ b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-action.dtx @@ -0,0 +1,813 @@ +% \iffalse meta-comment +% +%% File: l3pdfpdffield-action.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,siunitx} +\usepackage{l3pdffield-testphase,bearwear} +\hypersetup{pdfauthor=The LaTeX Project, + pdftitle=l3pdffield (LaTeX PDF management testphase bundle)} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +% +% \fi +% \providecommand\hook[1]{\texttt{#1}} +% \title{^^A +% The \pkg{l3pdffield-action} module\\ Commands to handle actions of 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-action} Introduction} +% This is the documentation for actions for formular fields, for general information about form fields +% check the documentation l3pdffield. +% +% \begin{center} +% \ExplSyntaxOn +% A:~ \pdffield_checkbox:n {name=A}\quad B:~\pdffield_checkbox:n {name=B}\par\bigskip +% \pdffield_pushbutton:n{name=all,caption=Reset~All,reset}\quad +% \pdffield_reset_new:nn{B}{fields=B} +% \pdffield_pushbutton:n{name=all,caption=Reset~B,reset=B}\quad +% \ExplSyntaxOff +% \end{center} +% +% Please keep in mind +% \begin{itemize} +% \item Not every PDF viewer supports form fields. +% \item Even if they support it, that doesn't mean that +% they support actions like Submit. +% \item The handling can depend on settings in the PDF viewer. +% \item Standards like pdf/A disable features of form fields too +% (as you typically can't change the PDF). +% \end{itemize} +% +% \section{Actions} +% +% Actions must be handled in three places: In the action dictionary (|/A|) +% of the annotation(s), in the additional action dictionary of the field (|/AA|), +% and in the additional action dictionary (|/AA|) of the annotation(s). The distinction +% between the two |/AA| dictionaries is relevant as field actions can only be +% added when the field is initialized, so typically with the first field command +% for a specific name, while annotation actions can be added for example only to +% one specific instance of a checkbox or to pushbuttons belonging to the same field. +% +% \subsection{The additional action dictionaries (AA)} +% The actions in the |/AA| dictionaries are JavaScript (ECMAScript) actions. +% An example is the |calculate|/|AA/C| action, which is added with the |/C| key: +% +% \begin{verbatim} +% Netto~\pdffield_textfield:n{name=netto}~ +% \pdf_object_unnamed_write:nx{stream} +% { +% {} +% { +% var~f_netto = this.getField("netto"); +% event.value = 1.19*f_netto.value; +% } +% } +% \tl_set:Nx\l_tmpa_tl{\pdf_object_ref_last:} +% Brutto~\pdffield_textfield:n{name=brutto,AA/C={\l_tmpa_tl}} +% \end{verbatim} +% +% The main problem with scripts is to get the escaping right. While it is possible +% to pass the script as string, it is less error prone to include it as (file) stream +% and to reference the object number as done in the example. +% +% \subsection{The action dictionary (A)} +% +% The action dictionary can contain much more action types. The PDF reference lists 20 +% different types\footnote{Sound and Movie are deprecated in PDF~2.0}: +% GoTo, GoToR, GoToE, GoToDp, Launch, Thread, URI, Sound, Movie, +% Hide, Named, SubmitForm, ResetForm, ImportData, SetOCGState, Rendition, +% Trans, GoTo3DView, JavaScript, RichMediaExecute. +% +% And action dictionary typically looks like this: +% \begin{verbatim} +% /A << /Type /Action +% /S ... % type name, e.g. /URI +% /Next ... % optional, next action +% ... ... % more keys +% >> +% \end{verbatim} +% +% The |/Next| key allows to chain actions. The value can be a reference to a +% single action, or an array of actions. +% +% It depends on the action type which other keys should be used. +% +% While almost all actions are usable in the annotations of a field, the three +% actions |SubmitForm|, |ResetForm| and |ImportData| are specific to fields and need +% explicit support. This support is the main task of this module. +% +% \subsubsection{ResetForm} +% The |ResetForm| action resets the fields of a form. The action is typically +% attached to a pushbutton. +% +% In simple cases the action only need to contain the subtype entry and then resets +% everything (sadly with some side-effect on the appearance of the pushbutton, sigh). +% +% \begin{verbatim} +% \group_begin: +% \pdfannot_dict_put:nnn{widget}{A}{<>} +% \pdffield_pushbutton:n{name=R,caption=Reset} +% \group_end: +% \end{verbatim} +% +% A |ResetForm| action knows two optional keys: |/Fields| allows to describe or restrict +% the fields which should be reset. Depending on the setting of the |/Flags| key +% the value of |/Fields| describes the fields to reset or the fields to leave unchanged. +% +% The commands of this module allow to store actions under a name which can then be +% used in the key-val list of a field annotation. +% +% A reset action can be defined and used like this +% \begin{verbatim} +% \pdffield_reset_new:nn +% {myreset} +% { +% fields= {A,B,C}, +% exclude % or include +% } +% \pdffield_pushbutton:n{name=r,caption=Reset,reset=myreset} +% \end{verbatim} +% +% |myreset| is the name the action can be referred to with the |reset| key. +% +% It is possible to define and use a reset action before all fields it +% refers too have been created. +% The list of names can contain names that are actually not used by the form. +% +% The reset action |all| is predefined. +% +% \subsubsection{ImportData} +% The |ImportData| action allows to import field data from an external file, for example +% a |.fdf| created with the submit action. +% The action is typically attached to a pushbutton, its only value is a file name. +% +% \subsubsection{SubmitForm} +% +% |SubmitForm| is the most challenging action. There are more keys in the dictionary, +% 13 flags, and there are four export options, which require each some flag settings. +% And the main argument is an url, which can contain special chars like \# or \% and +% so need special handling. +% +% A submit action can be defined like this +% \begin{verbatim} +% \pdffield_submit_new:nnn +% {mysubmit} +% { +% export = fdf, +% fields= {A,B,C}, +% exclude, % or include +% setsubmitflags={...} +% ... +% } +% {URL} +% \pdffield_pushbutton:n{name=s,caption={Submit~A,B,C},submit=mysubmit} +% \end{verbatim} +% +% The export options are |html|, |pdf|, |fdf| and |xfdf|. The |html| export uses +% my default the |POST| method, the |GET| method can be forced by setting the +% |GetMethod| flag---at least according to the reference, I wasn't able yet to test it. +% +% +% The following tabular describes the relation between these export options and the +% flags. |0| and |1| in the tabular means that the value is set by the code. |*| +% can be set by the user with the |setFlags| or |setsubmitflags| key. +% +% \begin{center} +% \begin{tabular}{lcccc} +% Flag & html & pdf & fdf & xfdf \\\hline +% Include/Exclude & * & 0 & * & * \\ +% IncludeNoValueFields & * & 0 & * & * \\ +% ExportFormat & 1 & 0 & 0 & 0 \\ +% GetMethod & * & 0 & 0 & 0 \\ +% SubmitCoordinates & * & 0 & 0 & 0 \\ +% XFDF & 0 & 0 & 0 & 1 \\ +% IncludeAppendSaves & 0 & 0 & * & 0 \\ +% IncludeAnnotations & 0 & 0 & * & 0 \\ +% SubmitPDF & 0 & 1 & 0 & 0 \\ +% CanonicalFormat & * & 0 & * & * \\ +% ExclNonUserAnnots & 0 & 0 & * & 0 \\ +% ExclFKey & 0 & 0 & * & 0 \\ +% EmbedForm & 0 & 0 & * & 0 \\% +% \end{tabular} +% \end{center} +% +% \bigskip +% \subsection{Commands} +% \begin{function}{\pdffield_reset_new:nn} +% \begin{syntax} +% \cs{pdffield_reset_new:nn}\Arg{name}\Arg{key val list} +% \end{syntax} +% This defines an new reset action with the name \meta{name}. +% The keys are described below. +% \end{function} +% +% \begin{function}{\pdffield_submit_new:nnn} +% \begin{syntax} +% \cs{pdffield_submit_new:nn}\Arg{name}\Arg{key val list}\Arg{URL} +% \end{syntax} +% This defines an submit action with the name \meta{name}. +% The keys are described below. \meta{URL} should be given verbatim. +% That means \# and \% should not be escaped. The URL should be +% correctly percent encoded, or the |urlencode| key should +% be used then the code will create the percent encoding. +% +% \meta{URL} can be a mail address and should then start with |mailto:|. +% A subject can be attached with |?subject=...|. +% This normally works quite fine as it only needs a correctly working mail programm. +% (But for some unknown reason my mail program don't like mail addresses with hyphens in them). +% +% Alternativly it should be an URL of a script, which should return the correct +% answer (which one this is, is rather unclear). +% +% \end{function} +% +% \subsection{Keys for the commands to create actions} +% \begin{function}{fields} +% \begin{syntax} +% |fields| = \Arg{comma list of fully qualified field names} +% \end{syntax} +% |fields| is a comma list of \emph{fully qualified} field names, typically this can +% be the short name set with |name| in a field declaration, but in complex fieldsets +% it is needed to include the parents in the name too, separated by periods. +% If |exclude| is set, this list describes the fields that should +% be excluded from the reset or the submission. +% The default is |include|: the list describes the fields +% to reset or submit. Descendant of fields are reset or submitted too! +% +% The key is relevant for reset and submit actions. +% \end{function} +% +% \begin{function}{include, exclude} +% \begin{syntax} +% |include| \\ +% |exclude| +% \end{syntax} +% These keys are shorthands to unset/set the |Include/Exclude| flag and decide +% if the list of fields in the |fields| key are included or +% excluded. The default is |include|: the list describes the fields +% to reset or submit. +% +% The keys are relevant for reset and submit actions. +% \end{function} + +% \begin{function}{urlencode} +% \begin{syntax} +% |urlencode| = |true|\verb+|+|false| +% \end{syntax} +% When this is true the code will percent encode the submission URL. +% This is needed if the URL contains for example non-ascii chars or spaces. +% \end{function} +% +% \begin{function}{setsubmitflags,setFlags,unsetsubmitflags,unsetFlags} +% \begin{syntax} +% |setsubmitflags| = \Arg{comma list of flags}\\ +% |setFlags| = \Arg{comma list of flags}\\ +% |unsetsubmitflags| = |all| \verb"|" \Arg{comma list of flags}\\ +% |unsetFlags| = |all| \verb"|" \Arg{comma list of flags} +% \end{syntax} +% These keys accept a list of flag names and then sets or unsets them, the resulting value +% is then used with the \texttt{/Flags} key of a submit action. |Include/Exclude| +% is also used by a reset action andcan also be set with the |exclude| and |include| +% keys. Depending on the export type of the submit action some flags are set by the code. +% See the tabular above for details. +% The flag name can be given in PDF spelling (\texttt{IncludeNoValueFields}), +% in lowercase (\texttt{includenovaluefields}), and as number. |unsetFlags| and its +% alias |unsetsubmitflags| know the special value |all| which clears all the fields. +% +% The list of flags are: +% |Include/Exclude|, |IncludeNoValueFields|, |ExportFormat|, |GetMethod|, +% |SubmitCoordinates|, |XFDF|, |IncludeAppendSaves|, |IncludeAnnotations|, +% |SubmitPDF|, |CanonicalFormat|, |ExclNonUserAnnots|, |ExclFKey|, |EmbedForm| +% \end{function} +% +% \begin{function}{next} +% \begin{syntax} +% |next| = \meta{object reference} +% \end{syntax} +% This allows to add a follow up action to the |/Next| key. The value is expanded, so can +% be given as |\pdf_object_ref:n{name}| and point to a suitable object. +% \end{function} +% +% \subsection{Keys for fields} +% With the following keys actions can be attached to the annotation of a form field, +% for example a pushbutton. +% +% \begin{function}{reset,submit} +% \begin{syntax} +% |reset| = \meta{name}\\ +% |submit| = \meta{name} +% \end{syntax} +% This adds the reset or submit action \meta{name} as action to the annotation. +% The action should be +% been defined first. The actions are mutually exclusive, only one action can +% be added. If more actions are needed use the |next| key. +% For reset the default value |all| exists and it is used if the key is used +% without value. +% \end{function} +% +% \begin{function}{import} +% \begin{syntax} +% |import| = \meta{file name} +% \end{syntax} +% This adds an import action to the annotation. \meta{file name} should +% be for example the name of a |.fdf| file. If the name contains a path use a +% slash as separator. non-ascii chars should work, but ascii is safer. +% The action is mutually exclusive to submit and reset. +% \end{function} +% \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 +% ,\bool_if:NTF +% ,\box_dp:N +% ,\box_ht:N +% ,\l_tmpa_box +% ,\char_set_catcode_other:N +% ,\clist_map_inline:nn +% ,\color_export:nnN +% ,\color_set:nn +% ,\color_set:nnn +% ,\cs_new_protected:Npn +% ,\cs_new_protected:cpn +% ,\cs_set_eq:NN +% ,\cs_gset_eq:cN +% ,\cs_if_exist:cTF +% ,\cs_set_protected:Npn +% ,\cs_generate_variant:Nn +% ,\cs_gset_eq:NN +% ,\csname +% ,\dim_eval:n +% ,\dim_new:N +% ,\dim_set:N +% ,\endcsname +% ,\exp_args:Ne +% ,\exp_args:Nnx +% ,\exp_args:Nx +% ,\fboxsep +% ,\group_begin: +% ,\group_end: +% ,\hbox_to_wd:nn +% ,\hbox_set:Nn +% ,\hfill +% ,\hook_gput_code:nnn +% ,\int_eval:n +% ,\int_gincr:N +% ,\int_new:N +% ,\int_use:N +% ,\l_keys_choice_int +% ,\keys_define:nn +% ,\keys_set:nn +% ,\mode_leave_vertical: +% ,\makebox +% ,\msg_error:nnn +% ,\msg_error:nnnn +% ,\msg_new:nnn +% ,\msg_warning:nn +% ,\msg_warning:nnn +% ,\msg_warning:nnnnn +% ,\msg_warning:nnnn +% ,\NeedsTeXFormat +% ,\normalsize +% ,\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:nn +% ,\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_get:nnN +% ,\pdfdict_new:n +% ,\pdfdict_put:nnn +% ,\pdfdict_remove:nn +% ,\pdfdict_use:n +% ,\pdfdict_put:nnx +% ,\pdfmanagement_add:nnn +% ,\pdfmeta_standard_verify:nTF +% ,\pdfxform_if_exist:nTF +% ,\pdfxform_new:nnn +% ,\pdfxform_ref:n +% ,\phantom +% ,\prg_do_nothing: +% ,\ProvidesExplPackage +% ,\rule +% ,\seq_gput_right:Nn +% ,\seq_if_exist:NTF +% ,\seq_new:N +% ,\seq_use:Nn +% ,\seq_clear:N +% ,\seq_put_right:NV +% ,\str_if_empty:NTF +% ,\str_if_in:NnTF +% ,\str_new:N +% ,\strut +% ,\strutbox +% ,\tl_if_empty:NTF +% ,\tl_if_empty:NT +% ,\tl_if_empty:NF +% ,\tl_put_left:Nn +% ,\tl_if_empty:nTF +% ,\tl_if_head_eq_charcode:nNTF +% ,\tl_put_right:Nn +% ,\tl_new:N +% ,\tl_set:Nn +% ,\tl_to_str:n +% ,\tl_const:cn +% ,\tl_use:c +% ,\use:c +% } +% \section{\pkg{l3pdffield-action} Implementation} +% \begin{macrocode} +%<*package> +%<@@=pdffield> +% \end{macrocode} +% \subsection{Messages} +% \begin{macrocode} +\msg_new:nnn {pdffield}{action-name-undefined} + { + The~`#1`~action~name~`#2`~is~not~defined~and~ + will~be~ignored. + } + +% \end{macrocode} +% \subsection{Variables} +% \begin{variable} +% { +% ,\l_@@_action_export_tl +% ,\l_@@_action_Fields_seq +% ,\l_@@_action_next_tl +% } +% We need to store the export, fields and next value into variables. +% \begin{macrocode} +\tl_new:N \l_@@_action_export_tl +\seq_new:N \l_@@_action_Fields_seq +\tl_new:N \l_@@_action_next_tl +% \end{macrocode} +% \end{variable} +% \subsection{dictionaries} +% \begin{macro}{l_@@/ResetForm,l_@@/SubmitForm} +% We define two dictionaries to handle the reset and submit code. +% \begin{macrocode} +\pdfdict_new:n {l_@@/ResetForm} +\pdfdict_put:nnn {l_@@/ResetForm}{Type}{/Action} +\pdfdict_put:nnn {l_@@/ResetForm}{S}{/ResetForm} +\pdfdict_new:n {l_@@/SubmitForm} +\pdfdict_put:nnn {l_@@/SubmitForm}{Type}{/Action} +\pdfdict_put:nnn {l_@@/SubmitForm}{S}{/SubmitForm} +% \end{macrocode} +% \end{macro} +% \subsection{bitset for submit action} +% \begin{variable}{\l_@@_Flags_bitset} +% A bitset for the submit (and the one reset) flags: +% \begin{macrocode} +\bitset_new:Nn \l_@@_Flags_bitset + { + Include/Exclude = 1 + ,IncludeNoValueFields = 2 + ,ExportFormat = 3 + ,GetMethod = 4 + ,SubmitCoordinates = 5 + ,XFDF = 6 + ,IncludeAppendSaves = 7 + ,IncludeAnnotations = 8 + ,SubmitPDF = 9 + ,CanonicalFormat = 10 + ,ExclNonUserAnnots = 11 + ,ExclFKey = 12 + ,EmbedForm = 14 + ,include/exclude = 1 + ,includenovaluefields = 2 + ,exportformat = 3 + ,getmethod = 4 + ,submitcoordinates = 5 + ,xfdf = 6 + ,includeappendsaves = 7 + ,includeannotations = 8 + ,submitpdf = 9 + ,canonicalformat = 10 + ,exclnonuserannots = 11 + ,exclfkey = 12 + ,embedform = 14 + } +% \end{macrocode} +% \end{variable} +% \begin{macro} +% { +% \@@_action_flags_pdf: +% ,\@@_action_flags_html: +% ,\@@_action_flags_fdf: +% ,\@@_action_flags_xfdf: +% } +% The following commands sets the forced flags for the export options. +% \begin{macrocode} +\cs_new_protected:Npn \@@_action_flags_pdf: + { + \bitset_clear:N \l_@@_Flags_bitset + \bitset_set_true:Nn \l_@@_Flags_bitset { SubmitPDF } + } + +\cs_new_protected:Npn \@@_action_flags_html: + { + \bitset_set_true:Nn \l_@@_Flags_bitset { ExportFormat } + \bitset_set_false:Nn \l_@@_Flags_bitset { XFDF } + \bitset_set_false:Nn \l_@@_Flags_bitset { IncludeAppendSaves } + \bitset_set_false:Nn \l_@@_Flags_bitset { IncludeAnnotations } + \bitset_set_false:Nn \l_@@_Flags_bitset { SubmitPDF } + \bitset_set_false:Nn \l_@@_Flags_bitset { ExclNonUserAnnots } + \bitset_set_false:Nn \l_@@_Flags_bitset { ExclFKey } + \bitset_set_false:Nn \l_@@_Flags_bitset { EmbedForm } + } + +\cs_new_protected:Npn \@@_action_flags_fdf: + { + \bitset_set_false:Nn \l_@@_Flags_bitset { ExportFormat } + \bitset_set_false:Nn \l_@@_Flags_bitset { GetMethod } + \bitset_set_false:Nn \l_@@_Flags_bitset { SubmitCoordinates } + \bitset_set_false:Nn \l_@@_Flags_bitset { XFDF } + \bitset_set_false:Nn \l_@@_Flags_bitset { SubmitPDF } + } + +\cs_new_protected:Npn \@@_action_flags_xfdf: + { + \bitset_set_false:Nn \l_@@_Flags_bitset { ExportFormat } + \bitset_set_false:Nn \l_@@_Flags_bitset { GetMethod } + \bitset_set_false:Nn \l_@@_Flags_bitset { SubmitCoordinates } + \bitset_set_true:Nn \l_@@_Flags_bitset { XFDF } + \bitset_set_false:Nn \l_@@_Flags_bitset { IncludeAppendSaves } + \bitset_set_false:Nn \l_@@_Flags_bitset { IncludeAnnotations } + \bitset_set_false:Nn \l_@@_Flags_bitset { SubmitPDF } + \bitset_set_false:Nn \l_@@_Flags_bitset { ExclNonUserAnnots } + \bitset_set_false:Nn \l_@@_Flags_bitset { ExclFKey } + \bitset_set_false:Nn \l_@@_Flags_bitset { EmbedForm } + } +% \end{macrocode} +% \end{macro} +% \subsection{Keys} +% \begin{macro}{reset,submit,import} +% These are the three additional keys for the field annotations +% \begin{macrocode} +\keys_define:nn { pdffield } + { + reset .code:n = + { + \cs_if_exist:cTF { @@_action_reset_#1: } + { + \use:c { @@_action_reset_#1: } + \pdfannot_dict_put:nnx{widget} + {A} + {\tl_use:c { c_@@_action_reset_#1_tl } } + } + { + \msg_warning:nnnn{pdffield}{action-name-undefined}{reset}{#1} + } + } + ,reset .default:n = all + } + +\keys_define:nn { pdffield } + { + submit .code:n = + { + \cs_if_exist:cTF { @@_action_submit_#1: } + { + \use:c { @@_action_submit_#1: } + \pdfannot_dict_put:nnx{widget} + {A} + {\tl_use:c { c_@@_action_submit_#1_tl } } + } + { + \msg_warning:nnnn{pdffield}{action-name-undefined}{submit}{#1} + } + } + } + +\keys_define:nn { pdffield } + { + import .code:n = + { + \pdf_string_from_unicode:nnN {utf8/string}{#1}\l_@@_tmpa_str + \pdf_object_unnamed_write:nx {dict}{/Type/Action/S/ImportData/F\l_@@_tmpa_str} + \pdfannot_dict_put:nnx{widget} + {A} + {\pdf_object_ref_last: } + } + } + +% \end{macrocode} +% \end{macro} +% \begin{macro}{fields,exclude,include,export,charset,urlencode,next} +% These are keys used when defining the actions. +% \begin{macrocode} +\keys_define:nn { pdffield / action } + { + fields .code:n = + { + \clist_map_inline:nn {#1} + { + \pdf_string_from_unicode:nnN {utf8/string}{##1}\l_@@_tmpa_str + \seq_put_right:NV\l_@@_action_Fields_seq \l_@@_tmpa_str + } + } + ,exclude .code:n = { \bitset_set_true:Nn \l_@@_Flags_bitset {Include/Exclude }} + ,include .code:n = { \bitset_set_false:Nn \l_@@_Flags_bitset {Include/Exclude }} + ,export .choices:nn = {pdf,fdf,html,xfdf} + { + \tl_set:Nn \l_@@_action_export_tl {#1} + } + ,export .initial:n = {html} + ,charset .choices:nn = + {utf-8, utf-16, Shift-JIS, BigFive, GBK, UHC} + { \pdfdict_put:nnn { l_@@/SubmitForm }{#1} } + ,urlencode .bool_set:N = \l_@@_url_encode_bool + ,next .tl_set:N = \l_@@_action_next_tl + } +% \end{macrocode} +% \end{macro} +% \begin{macro}{setFlags,setsubmitflags,unsetFlags,unsetsubmitflags} +% \begin{macrocode} +\keys_define:nn { pdffield / action } + { + ,setFlags .code:n = + { + \clist_map_inline:nn {#1} + { + \bitset_set_true:Nn \l_@@_Flags_bitset {##1} + } + } + ,setsubmitflags .meta:n = {setFlags={#1}} + ,unsetFlags .multichoice: + ,unsetFlags / all .code:n = { \bitset_clear:N \l_@@_Flags_bitset} + ,unsetFlags / unknown .code:n = + { + \bitset_set_false:Nn \l_@@_Flags_bitset {#1} + } + ,unsetsubmitflags .meta:n = {unsetFlags={#1}} + } +% \end{macrocode} +% \end{macro} +% +% \subsection{New reset action} +% +% \begin{macro}{ \@@_action_reset_new:nn } +% The command defines a command which will setup the dictionary at first use, +% and then store the reference in a constant. +% \begin{macrocode} +\cs_new_protected:Npn \@@_action_reset_new:nn #1 #2 %#1 name, #2 keyval + { + \cs_new_protected:cpn {@@_action_reset_#1:} + { + \group_begin: + \seq_clear:N \l_@@_action_Fields_seq + \keys_set:nn { pdffield / action }{ #2 } + \pdf_object_unnamed_write:nx + { array } + { \seq_use:Nn \l_@@_action_Fields_seq {~} } + \tl_if_empty:NF \l_@@_action_next_tl + { + \pdfdict_put:nnx {l_@@/ResetForm}{Next}{\l_@@_action_next_tl} + } + \pdfdict_put:nnx + { l_@@/ResetForm } + { Fields } + { \pdf_object_ref_last: } + \pdfdict_put:nnx + { l_@@/ResetForm } + { Flags } + { \bitset_item:Nn\l_@@_Flags_bitset{Include/Exclude} } + \pdf_object_unnamed_write:nx + { dict } + { \pdfdict_use:n{l_@@/ResetForm} } + \tl_const:cx { c_@@_action_reset_#1_tl } { \pdf_object_ref_last: } + \cs_gset_eq:cN {@@_action_reset_#1:} \prg_do_nothing: + \group_end: + } + } + +\@@_action_reset_new:nn {all}{fields={},exclude} +% \end{macrocode} +% \end{macro} +% +% \subsection{New submit action} +% \begin{macro}{\@@_action_submit_new:nn} +% Quite similar to the reset command, only that we have to use an auxiliary +% to grab the URL with suitable catcodes. +% \begin{macrocode} +\cs_new_protected:Npn \@@_action_submit_new:nn #1 #2 %#1 name, #2 keyval + { + \group_begin: + \char_set_catcode_other:N \% + \char_set_catcode_other:N \# + \@@_action_submit_new:nnn {#1}{#2} + } +\cs_new_protected:Npn \@@_action_submit_new:nnn #1 #2 #3 %#1 name, #2 keyval, #3 url + { + \group_end: + \cs_new_protected:cpn {@@_action_submit_#1:} + { + \group_begin: + \seq_clear:N \l_@@_action_Fields_seq + \bitset_clear:N \l_@@_Flags_bitset + \keys_set:nn {pdffield/action}{#2} + \use:c{ @@_action_flags_\l_@@_action_export_tl :} + \pdfdict_put:nnx + { l_@@/SubmitForm } + { Flags } + { \bitset_to_arabic:N \l_@@_Flags_bitset } + \tl_if_empty:NF \l_@@_action_next_tl + { + \pdfdict_put:nnx {l_@@/SubmitForm}{Next}{\l_@@_action_next_tl} + } + \bool_if:NTF \l_@@_url_encode_bool + { \pdf_string_from_unicode:nnN { utf8/URI } {#3}\l_@@_tmpa_str } + { \pdf_string_from_unicode:nnN { utf8/string }{#3}\l_@@_tmpa_str } + \pdf_object_unnamed_write:nx {dict} + { + /FS/URL + /F \l_@@_tmpa_str + } + \pdfdict_put:nnx + { l_@@/SubmitForm } + { F } + { \pdf_object_ref_last: } + \pdf_object_unnamed_write:nx + { dict } + { \pdfdict_use:n{ l_@@/SubmitForm } } + \tl_const:cx { c_@@_action_submit_#1_tl } { \pdf_object_ref_last: } + \cs_gset_eq:cN { @@_action_submit_#1: } \prg_do_nothing: + \group_end: + } + } + +% \end{macrocode} +% \end{macro} +% +% \subsection{User commands} +% \begin{macro}{\pdffield_reset_new:nn, \pdffield_submit_new:nnn} +% \begin{macrocode} +\cs_set_eq:NN \pdffield_reset_new:nn \@@_action_reset_new:nn +\cs_set_eq:NN \pdffield_submit_new:nnn \@@_action_submit_new:nn +% +% \end{macrocode} +% \end{macro} +%\end{implementation} + +% \PrintIndex diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-action.pdf b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-action.pdf new file mode 100644 index 0000000000..b06750156a Binary files /dev/null and b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-action.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-checkbox.dtx b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-checkbox.dtx index 681a8d7059..413b9ee317 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-checkbox.dtx +++ b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-checkbox.dtx @@ -68,7 +68,7 @@ % }^^A % } % -% \date{Version 0.95d, released 2021-05-14} +% \date{Version 0.95e, released 2021-06-14} % % \maketitle % \begin{documentation} @@ -116,14 +116,17 @@ % The |appearance| keys have a more checkbox specific % behaviour, other keys have other defaults than with the basic commands. % Additionally there -% are a small number of keys specific to a checkbox. +% are a small number of keys specific to a checkbox. +% For convenience a number of important keys are documented here too, even if +% they are already in the document from l3pdffield. % % % Disabled keys are % \begin{itemize} % \item |V|, |DV|, |AS|: use |checked| instead. % \item |FT| is overwritten. -% \item For checkboxes only the field flags |ReadOnly|, |Required| and |NoExport| make sense. +% \item For checkboxes only the field flags |ReadOnly|, |Required| and |NoExport| +% make sense. % |Radio|, |Pushbotton| are set automatically automatically by the code % as this is required for a checkbox. % \end{itemize} @@ -140,7 +143,7 @@ % |name| = \meta{partial name}\\ % |T| = \meta{partial name} % \end{syntax} -% This sets like the |T| key for fields the partial name of the field. The value +% This sets the partial name of the field. 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 checkboxes with the same partial name are annotations @@ -157,7 +160,8 @@ % \end{syntax} % \emph{For experts only!} % This allows to give the checkbox field a specific ID. This is only useful -% in the context of a larger fieldset or if you want to attach another annotation +% in the context of a larger fieldset, if for example you want to use +% the same partial name for more than one field, 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 @@ -219,8 +223,9 @@ % \meta{partial appearance name}|/Yes| and \meta{partial appearance name}|/Off| % has been created. The initial value is |pdffield/checkbox/default| % for the normal appearance and shows a \cs{texttimes}. -% The other appearance are not set by default. +% The other appearances are not set by default. % \end{function} +% % \begin{function}{checked} % \begin{syntax} % |checked| = |true|\verb"|"|false| @@ -231,6 +236,13 @@ % values for different instances, if one wants to confuse the user. % \end{function} % +% \begin{function}{value,default} +% \begin{syntax} +% |value| = |Yes|\verb"|"|Off|\\ +% |default| = |Yes|\verb"|"|Off|\\ +% \end{syntax} +% With checkboxes this two key are simply an alternative input for |checked|. +% \end{function} % % \subsection{Using with hyperref} % The \cs{CheckBox} command from hyperref also prints a label, something that the @@ -265,26 +277,123 @@ % \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 +% ,\box_dp:N +% ,\box_ht:N +% ,\clist_map_inline:nn +% ,\color_export:nnN +% ,\color_set:nn +% ,\color_set:nnn +% ,\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 +% ,\csname +% ,\dim_eval:n +% ,\dim_new:N +% ,\endcsname +% ,\exp_args:Ne +% ,\fboxsep +% ,\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:nnn +% ,\msg_error:nnnn +% ,\msg_new:nnn +% ,\msg_warning:nn +% ,\msg_warning:nnn +% ,\msg_warning:nnnnn +% ,\NeedsTeXFormat +% ,\normalsize +% ,\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_write:nn +% ,\pdf_string_from_unicode:nnN +% ,\pdfannot_box_ref_last: +% ,\pdfannot_dict_put:nnn +% ,\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 +% ,\rule +% ,\seq_gput_right:Nn +% ,\seq_if_exist:NTF +% ,\seq_new:N +% ,\seq_use:Nn +% ,\str_if_empty:NTF +% ,\str_if_in:NnTF +% ,\str_new:N +% ,\strut +% ,\strutbox +% ,\tl_if_empty:NTF +% ,\tl_if_empty:NT +% ,\tl_if_empty:NF +% ,\tl_put_left:Nn +% ,\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-checkbox} Implementation} % \begin{macrocode} %<*package> %<@@=pdffield> % \end{macrocode} % \subsection{Variables} -% \begin{macrocode} -% \end{macrocode} +% There are no specific variables. % \subsection{Messages} -% \begin{macrocode} -% \end{macrocode} +% There are no specific messages. % \subsection{Appearances} -% The default appearances are a cross (\cs{texttimes}), -% Every appearance should have two versions and follow the naming +% The default appearances are a quadratic frame with cross (\cs{texttimes}) if +% checked. +% User appearances should have two versions and follow the naming % module/\meta{name}/Yes and module/\meta{name}/Off. -% \begin{macro}{@@/checkbox/default_appearances:} +% \begin{macro} +% { +% \@@_checkbox_default_appearances:, +% pdffield/checkbox/default/Yes, +% pdffield/checkbox/default/Off +% } % This defines the standard appearance. It is setup at the first % use of a checkbox, and will adapt to the font family in use then. % \begin{macrocode} -\cs_new_protected:cn {@@/checkbox/default_appearances:} +\cs_new_protected:Npn \@@_checkbox_default_appearances: { \pdffield_appearance:nn {pdffield/checkbox/default/Yes} { @@ -302,13 +411,14 @@ [ \dim_eval:n { \box_ht:N\strutbox+\box_dp:N\strutbox } ] { \phantom{\texttimes} \strut } } - \cs_gset_eq:cN {@@/checkbox/default_appearances:} \prg_do_nothing: + \cs_gset_eq:NN \@@_checkbox_default_appearances: \prg_do_nothing: } % \end{macrocode} % \end{macro} % %\subsection{Creating the field} % A field should be created if the name doesn't exist +% \begin{macro}{ \@@_checkbox_field:n } % \begin{macrocode} \cs_new_protected:Npn \@@_checkbox_field:n #1 %name { @@ -320,15 +430,18 @@ } \cs_generate_variant:Nn \@@_checkbox_field:n {V} % \end{macrocode} +% \end{macro} % \subsection{Assembling the checkbox} - +% % \begin{macro}{\@@_checkbox:n} % \begin{macrocode} \cs_new_protected:Npn \@@_checkbox:n #1 { \group_begin: - \use:c {@@/checkbox/default_appearances:} + \@@_checkbox_default_appearances: \cs_set_eq:NN\@@_appearance_handler:nnn \@@_checkbox_appearance_handler:nnn + \cs_set_eq:NN\@@_value_handler:n \@@_checkbox_value_handler:n + \cs_set_eq:NN\@@_default_handler:n \@@_checkbox_default_handler:n % \end{macrocode} % Setting up the defaults. % \begin{macrocode} @@ -369,6 +482,8 @@ % Most keys are inherited simply the ones from the generic field and annot keys. % A key to decide if the box is initially checked or not. % We stay in the same family so that we can build a style. +% \begin{macro}{checked} +% This is a key specific for checkbox, it sets both field and annotation keys. % \begin{macrocode} \keys_define:nn { pdffield } { @@ -388,15 +503,41 @@ ,checked .default:n = {true} ,checked .groups:n = {checkbox} } -% \end{macrocode} -% And a key to set a dedicated field ID -% \begin{macrocode} -\keys_define:nn { pdffield } +\keys_define:nn { pdffield } { - fieldID .tl_set:N = \l_@@_fieldID_tl + ,__value .choice: + ,__value / Off .code:n = + { + \pdfdict_put:nnx { l_@@/field }{V} { /Off } + \pdfdict_put:nnx { l_@@/field }{DV}{ /Off } + \pdfannot_dict_put:nnn {widget}{AS}{ /Off } + } + ,__value / Yes .code:n = + { + \pdfdict_put:nnx { l_@@/field }{V} { /Yes } + \pdfdict_put:nnx { l_@@/field }{DV}{ /Yes } + \pdfannot_dict_put:nnn {widget}{AS}{ /Yes } + } } % \end{macrocode} +% \end{macro} +% \begin{macro}{\@@_checkbox_value_handler:n,\@@_checkbox_default_handler:n} +% |value| and |default| do the same as checked. +% \begin{macrocode} +\cs_new_protected:Npn \@@_checkbox_value_handler:n #1 + { + \keys_set:nn{pdffield}{__value={#1}} + } +\cs_new_protected:Npn \@@_checkbox_default_handler:n #1 + { + \keys_set:nn{pdffield}{__value={#1}} + } +% \end{macrocode} +% \end{macro} % \begin{macro}{\@@_checkbox_appearance_handler:nnn} +% Appearances must create a dictionary, so we define a special handler. +% \Arg{name} is the xform name without the /Yes, /Off, \Arg{type} is N, R, or D, +% \Arg{text} is a word for the error message. % \begin{macrocode} \cs_new_protected:Npn \@@_checkbox_appearance_handler:nnn #1 #2 #3 %name, type, text { @@ -431,3 +572,5 @@ % \end{macrocode} % \end{macro} %\end{implementation} + +% \PrintIndex diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-checkbox.pdf b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-checkbox.pdf index e4b957a528..21354721c7 100644 Binary files a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-checkbox.pdf and b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-checkbox.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-choice.dtx b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-choice.dtx new file mode 100644 index 0000000000..630552274a --- /dev/null +++ b/macros/latex/contrib/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} +% +% \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 +% +% \end{macrocode} +% \end{macro} +%\end{implementation} +% \PrintIndex diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-choice.pdf b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-choice.pdf new file mode 100644 index 0000000000..d881c1bedb Binary files /dev/null and b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-choice.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-pushbutton.dtx b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-pushbutton.dtx new file mode 100644 index 0000000000..fe969d7ea9 --- /dev/null +++ b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-pushbutton.dtx @@ -0,0 +1,765 @@ +% \iffalse meta-comment +% +%% File: l3pdfpdffield-pushbutton.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,siunitx} +\usepackage{l3pdffield-testphase,bearwear} +\hypersetup{pdfauthor=The LaTeX Project, + pdftitle=l3pdffield (LaTeX PDF management testphase bundle)} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +% +% \fi +% \providecommand\hook[1]{\texttt{#1}} +% \ExplSyntaxOn +% \pdffield_appearance:nn {pdffield/bear} +% { +% \tikz\bear\bearwear[shirt=red,body~deco={\node[font=\tiny\bfseries,white]~at~(beartummy){Push};}]; +% } +% \ExplSyntaxOff +% \title{^^A +% The \pkg{l3pdffield-pushbutton} module\\ Commands to create pushbutton 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-pushbutton} Introduction} +% This is the documentation for pushbutton fields, for general information about form fields +% check the documentation l3pdffield. +% +% +% +% Please keep in mind +% \begin{itemize} +% \item Not every PDF viewer supports pushbuttons. +% \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{Pushbuttons} +% Click me: +% \ExplSyntaxOn +% \group_begin: +% \tl_set:Nn\l_tmpa_tl{app.alert('Hello!~I\'m~Bär!',3,0);} +% \regex_replace_once:nnN{ä}{\x5Cu00E4}\l_tmpa_tl{} +% \pdf_object_unnamed_write:nx{stream}{{}{\exp_not:o{\l_tmpa_tl}}} +% \pdfannot_dict_put:nnx{widget}{A}{<>} +% \pdffield_pushbutton:n{name=bear,appearance=pdffield/bear,width=23pt,height=30pt,depth=10pt} +% \group_end: +% \ExplSyntaxOff +% +% \bigskip +% \subsection{Commands} +% \begin{function}{\pdffield_push:n} +% \begin{syntax} +% \cs{pdffield_push:n}\Arg{key val list} +% \end{syntax} +% This creates a pushbutton. Unlike radio buttons and checkboxes pushbuttons +% don't change their state and they don't store or represent a value. +% Instead their purpose is to trigger an \emph{action}. Important +% actions are for example Submit and Reset. +% +% Interfaces for such actions will be setup in another module later. +% For now actions should be added through the widget dictionary. The following +% for example setups a named action. +% +% \begin{verbatim} +% \group_begin: +% \pdfannot_dict_put:nnn {widget}{A}{<>} +% \sffamily\bfseries +% \pdffield_pushbutton:n +% {name=my/go, +% width=4cm, +% caption=go~to~last~page, +% rollover-caption=click~me!} +% \group_end: +% \end{verbatim} +% \begin{center} +% \ExplSyntaxOn +% \group_begin: +% \pdfannot_dict_put:nnn {widget}{A}{<>} +% \sffamily\bfseries\pdffield_pushbutton:n +% {name=my/go,width=4cm,caption=GO~TO~LAST~PAGE,rollover-caption=click~me!} +% \group_end: +% \ExplSyntaxOff +% \end{center} +% The list of allowed keys is described below. +% The \meta{key val list} should at least set the name, without it the default name +% |pushbutton| is used. +% \end{function} +% +% \subsection{The look of the button} +% Pushbuttons have no value. PDF compensates this by giving much more options to setup +% the appearance. Beside the standard |AP| key there are number of settings in the +% dynamic appearance dictionary |MK|. Sadly it is quite unclear how all this settings +% interact (or should interact), and PDF viewers don't honor all of them. I was for +% example not able to get the down appearance to show off. +% +% By default the code will draw (with l3draw) a button and place the caption and +% rollover-caption on it. The caption will honor the surrounding font, fontsize and +% the color, and will be placed on the baseline as described by the height and depth +% keys. +% +% +% +% \subsection{Keys} +% +% The new pushbutton 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 pushbutton specific +% behaviour, other keys have other defaults than with the basic commands. +% Additionally there +% are a small number of keys specific to a pushbutton. +% For convenience a number of important keys are documented here too, even if +% they are already in the document from l3pdffield. +% +% Disabled keys are +% \begin{itemize} +% \item |V|, |DV|. As a pushbutton has no permanent state, +% the keys should not be used. +% \item |FT| is overwritten. +% \item For pushbuttons only the field flags |ReadOnly|, |Required| and |NoExport| +% make sense. +% |Pushbutton| is set automatically by the code +% as this is required for a pushbutton. +% \end{itemize} +% +% \begin{function}{preset-pushbutton} +% \begin{syntax} +% |preset-pushbutton| = \Arg{key-val-list} +% \end{syntax} +% This allows to set default keys for a pushbutton. +% \end{function} +% +% \begin{function}{name,T} +% \begin{syntax} +% |name| = \meta{partial name}\\ +% |T| = \meta{partial name} +% \end{syntax} +% This sets the partial name of the field. 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 pushbuttons 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}{fieldID} +% \begin{syntax} +% |fieldID| = \meta{field ID}\\ +% \end{syntax} +% \emph{For experts only!} +% This allows to give the pushbutton 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}{altname,TU} +% \begin{syntax} +% |altname| = \meta{string}\\ +% |TU| = \meta{string}\\ +% \end{syntax} +% This is sets an alternative name for user interaction. +% This name can only be set at the first pushbutton instance, when the field is initialized. +% \end{function} +% +% \begin{function}{mappingname,TM} +% \begin{syntax} +% |mappingname| = \meta{string}\\ +% |TM| = \meta{string}\\ +% \end{syntax} +% This is sets an alternative name for export. +% This name can only be set at the first pushbutton instance, when the field is initialized. +% \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 pushbutton instance. +% The value should be a dimension expression. By default +% |width| is \qty{3}{\centi\meter}, |height| uses 1.05\cs{normalbaselineskip}, and +% |depth| is 0.45\cs{normalbaselineskip}. +% \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 keys sets the normal appearance, the rollover appearance (when the +% mouse hovers over the pushbutton) and the down appearance (when the +% mouse clicks). They take as value a +% \meta{appearance name} and expects that one form Xobjects +% with this name has been created before. +% It depends on the PDF viewer if such appearances +% are shown. adobe reader for example ignores the down appearance. +% \end{function} +% +% \begin{function}{action} +% \begin{syntax} +% |action| = .....\\ +% \end{syntax} +% This key doesn't exist yet. It will (probably) be added when a interface +% for actions are added. +% \end{function} +% +% \subsection{Using with hyperref} +% The \cs{Pushbutton} command from hyperref also adds a label. Something like +% this could more or less fake it. But be aware that the options are not +% identical. +% +% \begin{verbatim} +% \ExplSyntaxOn\makeatletter +% \def\@PushButton[#1]#2{\LayoutPushButtonField{#2}{\pdffield_pushbutton:n {name=#2,#1}}} +% \ExplSyntaxOff\makeatother +% \end{verbatim} +% +% +% \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 +% ,\box_dp:N +% ,\box_ht:N +% ,\l_tmpa_box +% ,\clist_map_inline:nn +% ,\color_export:nnN +% ,\color_set:nn +% ,\color_set:nnn +% ,\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 +% ,\csname +% ,\dim_eval:n +% ,\dim_new:N +% ,\dim_set:N +% ,\endcsname +% ,\exp_args:Ne +% ,\exp_args:Nnx +% ,\exp_args:Nx +% ,\fboxsep +% ,\group_begin: +% ,\group_end: +% ,\hbox_to_wd:nn +% ,\hbox_set:Nn +% ,\hfill +% ,\hook_gput_code:nnn +% ,\int_eval:n +% ,\int_gincr:N +% ,\int_new:N +% ,\int_use:N +% ,\l_keys_choice_int +% ,\keys_define:nn +% ,\keys_set:nn +% ,\mode_leave_vertical: +% ,\makebox +% ,\msg_error:nnn +% ,\msg_error:nnnn +% ,\msg_new:nnn +% ,\msg_warning:nn +% ,\msg_warning:nnn +% ,\msg_warning:nnnnn +% ,\NeedsTeXFormat +% ,\normalsize +% ,\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_write:nn +% ,\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_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 +% ,\rule +% ,\seq_gput_right:Nn +% ,\seq_if_exist:NTF +% ,\seq_new:N +% ,\seq_use:Nn +% ,\str_if_empty:NTF +% ,\str_if_in:NnTF +% ,\str_new:N +% ,\strut +% ,\strutbox +% ,\tl_if_empty:NTF +% ,\tl_if_empty:NT +% ,\tl_if_empty:NF +% ,\tl_put_left:Nn +% ,\tl_if_empty:nTF +% ,\tl_if_head_eq_charcode:nNTF +% ,\tl_put_right:Nn +% ,\tl_new:N +% ,\tl_set:Nn +% ,\tl_to_str:n +% ,\use:c +% } +% \section{\pkg{l3pdffield-pushbutton} Implementation} +% \begin{macrocode} +%<*package> +%<@@=pdffield> +% \end{macrocode} +% \subsection{Variables} +% A variable to store the appearance code, and two dimensions +% for the appearances. We can't use a single default +% appearance, so we use a count. +% \begin{variable} +% { +% ,\l_@@_pushbutton_appearance_code_tl +% ,\l_@@_pushbutton_linewidth_dim +% ,\l_@@_pushbutton_totalht_dim +% ,\g_@@_pushbutton_cnt_int +% } +% A pushbutton can setup the appearance only after the texts are known, +% so the code is stored and executed later. +% \begin{macrocode} +\tl_new:N \l_@@_pushbutton_appearance_code_tl +\dim_new:N \l_@@_pushbutton_linewidth_dim +\dim_new:N \l_@@_pushbutton_totalht_dim +\int_new:N \g_@@_pushbutton_cnt_int +% \end{macrocode} +% \end{variable} +% \subsection{Appearances} +% The default appearances are a rectangular frame with some text. +% +% \begin{macro} +% { +% \@@_pushbutton_default_appearances:, +% pdffield/pushbutton/default-n, +% pdffield/pushbutton/defaultrollover-n, +% pdffield/pushbutton/defaultdown-n, +% } +% This defines the standard appearances. They are setup at the first +% use of a pushbutton, and will adapt to the font family in use then. +% \begin{macrocode} +\dim_set:Nn \l_@@_pushbutton_linewidth_dim {0.4pt} +\color_set:nn {pdffield/push/text}{black} +\color_set:nn {pdffield/push/border}{black!95!white} +\color_set:nn {pdffield/push/bordertop}{yellow!5!white} +\color_set:nn {pdffield/push/borderbot}{black!50!white} +\color_set:nn {pdffield/push/fill}{black!20!white} + +\cs_new_protected:Npn \@@_pushbutton_default_appearances: + { + \int_gincr:N \g_@@_pushbutton_cnt_int + \exp_args:Nx + \pdffield_appearance:nn {pdffield/pushbutton/default-\int_use:N \g_@@_pushbutton_cnt_int} + { + \draw_begin: + \color_set:nn {pdffield/push/text}{.} + \dim_set:Nn \l_@@_pushbutton_totalht_dim + {\l_@@_annot_ht_dim + \l_@@_annot_dp_dim} + \draw_linewidth:n {\l_@@_pushbutton_linewidth_dim} + \draw_path_rectangle_corners:nn + {0.5\l_@@_pushbutton_linewidth_dim,0.5\l_@@_pushbutton_linewidth_dim} + { + \l_@@_annot_wd_dim-0.5\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-0.5\l_@@_pushbutton_linewidth_dim + } + \color_fill:n {pdffield/push/border} + \draw_path_use_clear:n { fill } + \draw_path_rectangle_corners:nn + {2\l_@@_pushbutton_linewidth_dim,2\l_@@_pushbutton_linewidth_dim} + { + \l_@@_annot_wd_dim-2\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-2\l_@@_pushbutton_linewidth_dim + } + \color_fill:n {pdffield/push/bordertop} + \draw_path_use_clear:n { fill } + \draw_path_moveto:n + { + 2\l_@@_pushbutton_linewidth_dim, + 2\l_@@_pushbutton_linewidth_dim + } + \draw_path_lineto:n + {5\l_@@_pushbutton_linewidth_dim,5\l_@@_pushbutton_linewidth_dim} + \draw_path_lineto:n + { + \l_@@_annot_wd_dim-5\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-5\l_@@_pushbutton_linewidth_dim + } + \draw_path_lineto:n + { + \l_@@_annot_wd_dim-2\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-2\l_@@_pushbutton_linewidth_dim + } + \draw_path_lineto:n + { + \l_@@_annot_wd_dim-2\l_@@_pushbutton_linewidth_dim, + 2\l_@@_pushbutton_linewidth_dim + } + \draw_path_close: + \color_fill:n {pdffield/push/borderbot} + \draw_path_use_clear:n { fill } + \draw_path_rectangle_corners:nn + { + 1.5\l_@@_pushbutton_linewidth_dim, + 1.5\l_@@_pushbutton_linewidth_dim + } + { + \l_@@_annot_wd_dim-1.5\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-1.5\l_@@_pushbutton_linewidth_dim + } + \color_stroke:n {pdffield/push/border} + \draw_path_use_clear:n { stroke } + \draw_path_rectangle_corners:nn + {4\l_@@_pushbutton_linewidth_dim,4\l_@@_pushbutton_linewidth_dim} + { + \l_@@_annot_wd_dim-4\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-4\l_@@_pushbutton_linewidth_dim + } + \color_fill:n {pdffield/push/fill} + \draw_path_use_clear:n { fill } + \color_fill:n {pdffield/push/text} + \draw_transform_shift:n + {0.5 \l_@@_annot_wd_dim, \l_@@_annot_dp_dim } + \hbox_set:Nn \l_tmpa_box { \makebox[0pt]{\l_@@_caption_tl} } + \draw_box_use:N \l_tmpa_box + \draw_end: + } + \exp_args:Nx + \pdffield_appearance:nn {pdffield/pushbutton/defaultrollover-\int_use:N \g_@@_pushbutton_cnt_int} + { + \draw_begin: + \dim_set:Nn \l_@@_pushbutton_totalht_dim + {\l_@@_annot_ht_dim + \l_@@_annot_dp_dim} + \draw_linewidth:n {\l_@@_pushbutton_linewidth_dim} + \draw_path_rectangle_corners:nn + {0.5\l_@@_pushbutton_linewidth_dim,0.5\l_@@_pushbutton_linewidth_dim} + { + \l_@@_annot_wd_dim-0.5\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-0.5\l_@@_pushbutton_linewidth_dim + } + \color_fill:n {pdffield/push/border} + \draw_path_use_clear:n { fill } + \draw_path_rectangle_corners:nn + {2\l_@@_pushbutton_linewidth_dim,2\l_@@_pushbutton_linewidth_dim} + { + \l_@@_annot_wd_dim-2\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-2\l_@@_pushbutton_linewidth_dim + } + \color_fill:n {pdffield/push/borderbot} + \draw_path_use_clear:n { fill } + \draw_path_moveto:n + { + 2\l_@@_pushbutton_linewidth_dim, + 2\l_@@_pushbutton_linewidth_dim + } + \draw_path_lineto:n + {5\l_@@_pushbutton_linewidth_dim,5\l_@@_pushbutton_linewidth_dim} + \draw_path_lineto:n + { + \l_@@_annot_wd_dim-5\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-5\l_@@_pushbutton_linewidth_dim + } + \draw_path_lineto:n + { + \l_@@_annot_wd_dim-2\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-2\l_@@_pushbutton_linewidth_dim + } + \draw_path_lineto:n + { + \l_@@_annot_wd_dim-2\l_@@_pushbutton_linewidth_dim, + 2\l_@@_pushbutton_linewidth_dim + } + \draw_path_close: + \color_fill:n {pdffield/push/bordertop} + \draw_path_use_clear:n { fill } + \draw_path_rectangle_corners:nn + { + 1.5\l_@@_pushbutton_linewidth_dim, + 1.5\l_@@_pushbutton_linewidth_dim + } + { + \l_@@_annot_wd_dim-1.5\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-1.5\l_@@_pushbutton_linewidth_dim + } + \color_stroke:n {pdffield/push/border} + \draw_path_use_clear:n { stroke } + \draw_path_rectangle_corners:nn + {4\l_@@_pushbutton_linewidth_dim,4\l_@@_pushbutton_linewidth_dim} + { + \l_@@_annot_wd_dim-4\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-4\l_@@_pushbutton_linewidth_dim + } + \color_fill:n {pdffield/push/fill} + \draw_path_use_clear:n { fill } + \color_fill:n {pdffield/push/text} + \draw_transform_shift:n + {0.5 \l_@@_annot_wd_dim, \l_@@_annot_dp_dim } + \hbox_set:Nn \l_tmpa_box { \makebox[0pt]{\l_@@_rollover_caption_tl} } + \draw_box_use:N \l_tmpa_box + \draw_end: + } + \exp_args:Nx + \pdffield_appearance:nn {pdffield/pushbutton/defaultdown-\int_use:N \g_@@_pushbutton_cnt_int} + { + \draw_begin: + \dim_set:Nn \l_@@_pushbutton_totalht_dim + {\l_@@_annot_ht_dim + \l_@@_annot_dp_dim} + \draw_linewidth:n {\l_@@_pushbutton_linewidth_dim} + \draw_path_rectangle_corners:nn + {0.5\l_@@_pushbutton_linewidth_dim,0.5\l_@@_pushbutton_linewidth_dim} + { + \l_@@_annot_wd_dim-0.5\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-0.5\l_@@_pushbutton_linewidth_dim + } + \color_fill:n {pdffield/push/border} + \draw_path_use_clear:n { fill } + \draw_path_rectangle_corners:nn + {2\l_@@_pushbutton_linewidth_dim,2\l_@@_pushbutton_linewidth_dim} + { + \l_@@_annot_wd_dim-2\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-2\l_@@_pushbutton_linewidth_dim + } + \color_fill:n {pdffield/push/borderbot} + \draw_path_use_clear:n { fill } + \draw_path_moveto:n + { + 2\l_@@_pushbutton_linewidth_dim, + 2\l_@@_pushbutton_linewidth_dim + } + \draw_path_lineto:n + {5\l_@@_pushbutton_linewidth_dim,5\l_@@_pushbutton_linewidth_dim} + \draw_path_lineto:n + { + \l_@@_annot_wd_dim-5\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-5\l_@@_pushbutton_linewidth_dim + } + \draw_path_lineto:n + { + \l_@@_annot_wd_dim-2\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-2\l_@@_pushbutton_linewidth_dim + } + \draw_path_lineto:n + { + \l_@@_annot_wd_dim-2\l_@@_pushbutton_linewidth_dim, + 2\l_@@_pushbutton_linewidth_dim + } + \draw_path_close: + \color_fill:n {pdffield/push/bordertop} + \draw_path_use_clear:n { fill } + \draw_path_rectangle_corners:nn + { + 1.5\l_@@_pushbutton_linewidth_dim, + 1.5\l_@@_pushbutton_linewidth_dim + } + { + \l_@@_annot_wd_dim-1.5\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-1.5\l_@@_pushbutton_linewidth_dim + } + \color_stroke:n {pdffield/push/border} + \draw_path_use_clear:n { stroke } + \draw_path_rectangle_corners:nn + {4\l_@@_pushbutton_linewidth_dim,4\l_@@_pushbutton_linewidth_dim} + { + \l_@@_annot_wd_dim-4\l_@@_pushbutton_linewidth_dim, + \l_@@_pushbutton_totalht_dim-4\l_@@_pushbutton_linewidth_dim + } + \color_fill:n {pdffield/push/fill} + \draw_path_use_clear:n { fill } + \color_fill:n {pdffield/push/text} + \draw_transform_shift:n + {0.5 \l_@@_annot_wd_dim, \l_@@_annot_dp_dim } + \hbox_set:Nn \l_tmpa_box { \makebox[0pt]{\l_@@_down_caption_tl} } + \draw_box_use:N \l_tmpa_box + \draw_end: + } + } +% \end{macrocode} +% \end{macro} +% +%\subsection{Creating the field} +% A field should be created if the name doesn't exist +% \begin{macro}{ \@@_pushbutton_field:n } +% \begin{macrocode} +\cs_new_protected:Npn \@@_pushbutton_field:n #1 %name + { + \pdf_object_if_exist:nF {@@/field/@@/pushbutton/#1} + { + \@@_field:n { @@/pushbutton/#1 } + } + \keys_set:nn {pdffield}{parent=@@/pushbutton/#1} + } +\cs_generate_variant:Nn \@@_pushbutton_field:n {V} +% \end{macrocode} +% \end{macro} +% \subsection{Assembling the Pushbutton} +% +% \begin{macro}{\@@_pushbutton:n} +% \begin{macrocode} +\cs_new_protected:Npn \@@_pushbutton:n #1 + { + \group_begin: + \tl_set:Nn\l_@@_pushbutton_appearance_code_tl{} + \cs_set_eq:NN\@@_appearance_handler:nnn \@@_pushbutton_appearance_handler:nnn +% \end{macrocode} +% Setting up the defaults. +% \begin{macrocode} + \keys_set:nn {pdffield} + { + fieldID=, + name=pushbutton, + width = 3cm, + height = 1.05\normalbaselineskip, + depth = 0.45\normalbaselineskip, + } +% \end{macrocode} +% Value keys should be undefined. +% \begin{macrocode} + \keys_set:nn { pdffield }{@@/preset/pushbutton,#1} + \keys_set:nn { pdffield } + { + ,V= + ,DV= + ,setFf={Pushbutton} + ,FT= Btn + } + \tl_if_empty:NT\l_@@_fieldID_tl + { + \pdfdict_get:nnN {l_@@/field}{T}\l_@@_fieldID_tl + \tl_put_left:Nn \l_@@_fieldID_tl {@@/pushbutton/} + } + \tl_if_empty:NT\l_@@_pushbutton_appearance_code_tl + { + \@@_pushbutton_default_appearances: + \exp_args:Nnx + \keys_set:nn {pdffield} + { + appearance = pdffield/pushbutton/default-\int_eval:n{ \g_@@_pushbutton_cnt_int}, + down-appearance = pdffield/pushbutton/defaultdown-\int_eval:n{ \g_@@_pushbutton_cnt_int}, + rollover-appearance = pdffield/pushbutton/defaultrollover-\int_eval:n{ \g_@@_pushbutton_cnt_int}, + } + } + \l_@@_pushbutton_appearance_code_tl + \@@_pushbutton_field:V\l_@@_fieldID_tl + \@@_annot: + \group_end: + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Keys} +% Most keys are inherited from the generic field and annot keys. +% We only need to handle the appearance in a special way. +% +% \begin{macro}{\@@_pushbutton_appearance_handler:nnn} +% \begin{macrocode} +\cs_new_protected:Npn \@@_pushbutton_appearance_handler:nnn #1 #2 #3 %name, type, text + { + \tl_put_right:Nn \l_@@_pushbutton_appearance_code_tl + { + \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} +% +% \subsection{user commands} +% \begin{macro}{\pdffield_pushbutton:n} +% \begin{macrocode} +\cs_set_eq:NN \pdffield_pushbutton:n \@@_pushbutton:n +% +% \end{macrocode} +% \end{macro} +%\end{implementation} + +% \PrintIndex diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-pushbutton.pdf b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-pushbutton.pdf new file mode 100644 index 0000000000..3ec4937ec8 Binary files /dev/null and b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-pushbutton.pdf differ 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} +% +% \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 +% +% \end{macrocode} +% \end{macro} +%\end{implementation} +% \PrintIndex diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-radiobutton.pdf b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-radiobutton.pdf index 5328b6e77e..9f53b703c6 100644 Binary files a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-radiobutton.pdf and b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-radiobutton.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-textfield.dtx b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-textfield.dtx index a8ea21042f..395955714f 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-textfield.dtx +++ b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-textfield.dtx @@ -53,7 +53,7 @@ % }^^A % } % -% \date{Version 0.95c, released 2021-03-17} +% \date{Version 0.95e, released 2021-06-14} % % \maketitle % \begin{documentation} @@ -187,6 +187,7 @@ % Disabled keys are % \begin{itemize} % \item |FT| is overwritten. +% \item |AS| is cleared. % \item |DA| is overwritten. % Locally use |fontcolor|, |fontsize| and |font| instead. % Globally you can set the |DA| key in the catalog with for example @@ -200,6 +201,10 @@ % set to 10 if it hasn't been set previously. % \end{itemize} % +% The keys |value| and |default| are mapped to |V| and |DV| for this field type, see +% below. +% +% % \begin{function}{preset-textfield} % \begin{syntax} % |preset-textfield| = \Arg{key-val-list} @@ -246,6 +251,7 @@ % with \cs{pdffield_field:nn}. % \end{function} % +% % \begin{function}{altname,TU} % \begin{syntax} % |altname| = \meta{string}\\ @@ -291,6 +297,25 @@ % make sense for a textfield). % \end{function} % +% \begin{function}{V,value} +% \begin{syntax} +% |V| = \meta{text}\\ +% |value| = \meta{text} +% \end{syntax} +% This sets the start text in the field. The keys have an effect only at the first +% instance of the textfield, when the field is initialized. +% \end{function} +% +% \begin{function}{DV,default} +% \begin{syntax} +% |DV| = \meta{text}\\ +% |default| = \meta{text} +% \end{syntax} +% This sets the text which is shown if the form is reset. +% The keys have an effect only at the first +% instance of the textfield, when the field is initialized. +% \end{function} +% % \begin{function}{fontcolor} % \begin{syntax} % |fontcolor| = \meta{color expression} \verb"|" [\meta{model}]\Arg{values}\\ @@ -340,41 +365,151 @@ % \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 +% ,\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 +% ,\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_write:nn +% ,\pdf_string_from_unicode:nnN +% ,\pdfannot_box_ref_last: +% ,\pdfannot_dict_put:nnn +% ,\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 +% ,\rule +% ,\seq_gput_right:Nn +% ,\seq_if_exist:NTF +% ,\seq_new:N +% ,\seq_use:Nn +% ,\smash +% ,\str_if_empty:NTF +% ,\str_if_in:NnTF +% ,\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_empty:nTF +% ,\tl_if_head_eq_charcode:nNTF +% ,\tl_new:N +% ,\tl_set:Nn +% ,\tl_to_str:n +% ,\use:c +% } % \section{\pkg{l3pdffield-textfield} Implementation} % \begin{macrocode} %<*package> %<@@=pdffield> % \end{macrocode} % \subsection{Variables} +% \begin{variable} +% { +% \l_@@_DA_fontcolor_tl, \l_@@_DA_fontsize_dim, \l_@@_DA_fontname_tl +% } +% Variables for the font setup in the DA key. % \begin{macrocode} \tl_new:N \l_@@_DA_fontcolor_tl \dim_new:N \l_@@_DA_fontsize_dim \tl_new:N \l_@@_DA_fontname_tl % \end{macrocode} -% \subsection{Messages} -% \begin{macrocode} -% \end{macrocode} +% \end{variable} +% % \subsection{Appearances} -% The default appearances are a cross (\cs{texttimes}), -% Every appearance should have two versions and follow the naming -% module/\meta{name}/Yes and module/\meta{name}/Off. -% \begin{macro}{@@/textfield/default_appearances:} +% The default appearance is a light gray background. +% +% \begin{macro}{\@@_textfield_default_appearance:} % This defines the standard appearance. It is setup at the first % use of a textfield. % \begin{macrocode} -\cs_new_protected:cn {@@/textfield/default_appearance:} +\cs_new_protected:Npn {\@@_textfield_default_appearance:} { \pdffield_appearance:nn {pdffield/textfield/default} { { \color_select:n{black!5!white}\rule{\paperwidth}{\paperheight} } } - \cs_gset_eq:cN {@@/textfield/default_appearance:} \prg_do_nothing: + \cs_gset_eq:NN \@@_textfield_default_appearance: \prg_do_nothing: } % \end{macrocode} % \end{macro} % %\subsection{Creating the field} -% A field should be created if the name doesn't exist +% \begin{macro}{\@@_textfield_field:n} +% A field should be created only if the name doesn't exist % \begin{macrocode} \cs_new_protected:Npn \@@_textfield_field:n #1 %name { @@ -386,17 +521,22 @@ } \cs_generate_variant:Nn \@@_textfield_field:n {V} % \end{macrocode} +% \end{macro} +% % \subsection{Assembling the textfield} - +% % \begin{macro}{\@@_textfield:n} +% At first we map the handler and setup the appearance. % \begin{macrocode} \cs_new_protected:Npn \@@_textfield:n #1 { \group_begin: - \cs_set_eq:NN\@@_value_handler:nN \@@_textfield_value_handler:nN - \use:c {@@/textfield/default_appearance:} + \cs_set_eq:NN\@@_V_handler:nN \@@_textfield_V_handler:nN + \cs_set_eq:NN\@@_value_handler:n \@@_textfield_value_handler:n + \cs_set_eq:NN\@@_default_handler:n \@@_textfield_default_handler:n + \@@_textfield_default_appearance: % \end{macrocode} -% Setting up the defaults. +% Setting up the defaults and processing the keys. % \begin{macrocode} \keys_set:nn {pdffield} { @@ -409,9 +549,10 @@ depth = \fp_eval:n {0.3*\f@size} pt, % font defaults!! } -% \end{macrocode} -% \begin{macrocode} \keys_set:nn { pdffield }{@@/preset/textfield,#1} +% \end{macrocode} +% We need to check if Comb is used and setup some flags in this case. +% \begin{macrocode} \int_compare:nNnT {\bitset_item:Nn \l_@@_Ff_bitset {Comb}}={1} { % warning if set? @@ -429,6 +570,9 @@ % warning } } +% \end{macrocode} +% Now the postprocessing. +% \begin{macrocode} \keys_set:nn { pdffield } { ,FT= Tx @@ -446,12 +590,14 @@ %\l_@@_text_DAextra_tl } } +% \end{macrocode} +% If no field ID exists, we get it from the 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 {@@/textfield/} } - \@@_textfield_field:V\l_@@_fieldID_tl \@@_annot: \group_end: @@ -463,6 +609,7 @@ % Most keys are inherited simply the ones from the generic field and annot keys. % A key to decide if the box is initially checked or not. % We stay in the same family so that we can build a style. +% \begin{macro}{fontcolor,fontsize,font} % \begin{macrocode} \keys_define:nn {pdffield} { @@ -482,23 +629,32 @@ ,fontsize .groups:n = {textfield} } % \end{macrocode} -% And a key to set a dedicated field ID -% \begin{macrocode} -\keys_define:nn { pdffield } - { - fieldID .tl_set:N = \l_@@_fieldID_tl - } -% \end{macrocode} +% \end{macro} % % \subsection{Handler} +% \begin{macro}{\@@_textfield_V_handler:nN} +% The handler for V/DV, it creates a string. % \begin{macrocode} -\cs_new_protected:Npn \@@_textfield_value_handler:nN #1#2 +\cs_new_protected:Npn \@@_textfield_V_handler:nN #1#2 { - \pdf_string_from_unicode:nnN {utf8/string}{#1}#2 + \pdf_string_from_unicode:nnN {utf16/hex}{#1}#2 } % \end{macrocode} -% -% \subsection{user commands} +% \end{macro} +% \begin{macro}{\@@_textfield_value_handler:n,\@@_textfield_default_handler:n} +% The handler for value and default. They simply map to V,DV here. +% \begin{macrocode} +\cs_new_protected:Npn \@@_textfield_value_handler:n #1 + { + \keys_set:nn{pdffield}{V={#1}} + } +\cs_new_protected:Npn \@@_textfield_default_handler:n #1 + { + \keys_set:nn{pdffield}{DV={#1}} + } +% \end{macrocode} +% \end{macro} +% \subsection{User command} % \begin{macro}{\pdffield_textfield:n} % \begin{macrocode} \cs_set_eq:NN \pdffield_textfield:n \@@_textfield:n @@ -506,3 +662,4 @@ % \end{macrocode} % \end{macro} %\end{implementation} +%\PrintIndex diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-textfield.pdf b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-textfield.pdf index 69a2e13b7d..ddbf333f3a 100644 Binary files a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-textfield.pdf and b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield-textfield.pdf differ 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} - {<>} + {<>} } }, 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} - {<>} + {<>} } }, ,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} % % \end{macrocode} diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield.pdf b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield.pdf index 903cd42c0a..12fd435f3e 100644 Binary files a/macros/latex/contrib/pdfmanagement-testphase/l3pdffield.pdf and b/macros/latex/contrib/pdfmanagement-testphase/l3pdffield.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffile.dtx b/macros/latex/contrib/pdfmanagement-testphase/l3pdffile.dtx index cf2176e439..81e2ef273e 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/l3pdffile.dtx +++ b/macros/latex/contrib/pdfmanagement-testphase/l3pdffile.dtx @@ -31,7 +31,7 @@ \documentclass[full]{l3doc} \usepackage{array,booktabs,hyperxmp} \hypersetup{pdfauthor=The LaTeX Project,pdftitle=l3pdffile (LaTeX PDF management testphase bundle)} - +\usepackage{caption} \providecommand\potentialclash{\noindent\llap{\dbend\ }} \begin{document} \DocInput{\jobname.dtx} @@ -53,7 +53,7 @@ % }^^A % } % -% \date{Version 0.95d, released 2021-05-14} +% \date{Version 0.95e, released 2021-06-14} % % \maketitle % \begin{documentation} @@ -245,13 +245,14 @@ % \end{function} % \begin{table} % \caption{Preset values in the file dictionaries\label{tab:filedict}} -% \begin{tabular}{lll} +% \hspace*{-3cm}\begin{tabular}{lll} % dictionary & key & value \\\hline % l\_pdffile & Type & /EmbeddedFile\\ % l\_pdffile/Params& Size & |\file_size:n{\l_pdffile_source_name_str}|\\ % l\_pdffile/Params& ModDate & |(\file_timestamp:n {\l_pdffile_source_name_str})|\\ % l\_pdffile/Params& CheckSum & |(\file_mdfive_hash:n{\l_pdffile_source_name_str})|\\ -% l\_pdffile/streamParams& & a /ModDate entry with year/month/date (used with \cs{pdffile_embed_stream:nnn})\\ +% l\_pdffile/streamParams& & a /ModDate entry with year/month/date \\ +% & & (used with \cs{pdffile_embed_stream:nnn})\\ % l\_pdffile/Filespec & Type & /Filespec\\ % l\_pdffile/Filespec & AFRelationship &Unspecified % \end{tabular} @@ -324,6 +325,28 @@ % The stream should not be too long, at least PS imposes a size limit for strings. % \end{function} % +% \begin{function}{\pdffile_filespec:nnn,\pdffile_filespec:nnx} +% \begin{syntax} +% \cs{ pdffile_filespec:nnn }\Arg{object name}\Arg{file name}{stream object reference} +% \end{syntax} +% The previous commands are fine if stream and filespec dictionary can be created together. +% But there are cases where the |filespec| dictionary should be referenced when the +% stream object doesn't exist yet. For example in the |AF| key of a structure at +% the begin of an environment where the stream is created from the body. +% +% This command allows to write a filespec dictionary alone and reference a previously +% created stream. +% +% \begin{verbatim} +% \pdf_object_new:nn{module/filespec/A}{dict} % a new filespec object +% \pdf_object_ref:n {module/filespec/A} % a reference +% \pdf_object_unnamed_write:nn { stream }{ {...}{content} } %writing the stream +% % filling and writing the filespec dictionary: +% \pdffile_filespec:nnn {module/filespec/A}{A.xml}{\pdf_object_ref_last:} +% \end{verbatim} +% +% \end{function} +% % \begin{variable}{\g_pdffile_mimetypes_prop} % This property contains a list of extensions and their mimetypes. % Values can be added or changed with the standard commands: @@ -377,7 +400,7 @@ % % \begin{macrocode} %<*header> -\ProvidesExplPackage{l3pdffile}{2021-05-14}{0.95d} +\ProvidesExplPackage{l3pdffile}{2021-06-14}{0.95e} {embedding and referencing files in PDF---LaTeX PDF management testphase bundle} \RequirePackage{l3pdftools} %temporarly!! % @@ -636,7 +659,8 @@ } } - +\cs_set_eq:NN \pdffile_filespec:nnn \@@_filespec_write:nnn +\cs_generate_variant:Nn \pdffile_filespec:nnn {nnx} %#1 {source filename} %#2 {target filename} %#3 { filespec object name } (will internally get a prefix! ??) diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdffile.pdf b/macros/latex/contrib/pdfmanagement-testphase/l3pdffile.pdf index b9b9a92b26..d5163b066e 100644 Binary files a/macros/latex/contrib/pdfmanagement-testphase/l3pdffile.pdf and b/macros/latex/contrib/pdfmanagement-testphase/l3pdffile.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdfmanagement.dtx b/macros/latex/contrib/pdfmanagement-testphase/l3pdfmanagement.dtx index 9383c03290..567bbc58a0 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/l3pdfmanagement.dtx +++ b/macros/latex/contrib/pdfmanagement-testphase/l3pdfmanagement.dtx @@ -61,7 +61,7 @@ % }^^A % } % -% \date{Version 0.95d, released 2021-05-14} +% \date{Version 0.95e, released 2021-06-14} % % \maketitle % \begin{documentation} @@ -557,7 +557,7 @@ %<@@=pdfmanagement> %<*header> % -\ProvidesExplPackage{l3pdfmanagement}{2021-05-14}{0.95d} +\ProvidesExplPackage{l3pdfmanagement}{2021-06-14}{0.95e} {Management of core PDF dictionaries (LaTeX PDF management testphase bundle)} % % \end{macrocode} @@ -914,9 +914,12 @@ % push to the register command / issue the special \cs_new_protected:Npn \@@_Pages_gpush: { - \exp_args:Nx \__pdf_backend_Pages_primitive:n + \pdfdict_if_empty:nF { g__pdf_Core/Pages} { - \pdfdict_use:n { g__pdf_Core/Pages} + \exp_args:Nx \__pdf_backend_Pages_primitive:n + { + \pdfdict_use:n { g__pdf_Core/Pages} + } } } diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdfmanagement.pdf b/macros/latex/contrib/pdfmanagement-testphase/l3pdfmanagement.pdf index b35c3a3a4d..f065b63c72 100644 Binary files a/macros/latex/contrib/pdfmanagement-testphase/l3pdfmanagement.pdf and b/macros/latex/contrib/pdfmanagement-testphase/l3pdfmanagement.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdfmeta.dtx b/macros/latex/contrib/pdfmanagement-testphase/l3pdfmeta.dtx index 44ea8a9191..f78fc98375 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/l3pdfmeta.dtx +++ b/macros/latex/contrib/pdfmanagement-testphase/l3pdfmeta.dtx @@ -53,7 +53,7 @@ % }^^A % } % -% \date{Version 0.95d, released 2021-05-14} +% \date{Version 0.95e, released 2021-06-14} % % \maketitle % \begin{documentation} @@ -220,6 +220,9 @@ % this will e.g. be checked by the new hyperref driver. % \item[|annot_widget_no_A_AA|] (rule 6.9-2) no A and AA dictionary in widget. % \item[|form_no_AA|] (6.9-3) no /AA dictionary in form field +% \item[|unicode|] that is set in the U-standards, A-2u and A-3u and means that +% every text should be in unicode. This is not something that can be enforced or +% tested from TeX, but in a current LaTeX normally ToUnicode are set for all fonts. % \end{description} % % \subsubsection{Tests with values and special handlers} @@ -340,7 +343,7 @@ % \begin{macrocode} %<@@=pdfmeta> %<*header> -\ProvidesExplPackage{l3pdfmeta}{2021-05-14}{0.95d} +\ProvidesExplPackage{l3pdfmeta}{2021-06-14}{0.95e} {PDF-Standards---LaTeX PDF management testphase bundle} % % \end{macrocode} @@ -513,7 +516,9 @@ % \begin{variable}{ % \g_@@_standard_pdf/A-1B_prop , % \g_@@_standard_pdf/A-2B_prop , -% \g_@@_standard_pdf/A-3B_prop +% \g_@@_standard_pdf/A-2U_prop , +% \g_@@_standard_pdf/A-3B_prop , +% \g_@@_standard_pdf/A-3U_prop , % } % \begin{macrocode} \prop_new:c { g_@@_standard_pdf/A-1B_prop } @@ -521,6 +526,8 @@ { ,name = pdf/A-1B ,type = A + ,level = 1 + ,conformance = B ,year = 2005 ,min_pdf_version = 1.4 %minimum ,no_encryption = @@ -580,11 +587,25 @@ { g_@@_standard_pdf/A-2B_prop }{name}{pdf/A-2B} \prop_gput:cnn { g_@@_standard_pdf/A-2B_prop }{year}{2011} +\prop_gput:cnn + { g_@@_standard_pdf/A-2B_prop }{level}{2} % embedding files is allowed (with restrictions) \prop_gremove:cn { g_@@_standard_pdf/A-2B_prop } { embed_content} +%A-2u ============== +\prop_new:c { g_@@_standard_pdf/A-2U_prop } +\prop_gset_eq:cc + { g_@@_standard_pdf/A-2U_prop } + { g_@@_standard_pdf/A-2B_prop } +\prop_gput:cnn + { g_@@_standard_pdf/A-2U_prop }{name}{pdf/A-2U} +\prop_gput:cnn + { g_@@_standard_pdf/A-2U_prop }{conformance}{U} +\prop_gput:cnn + { g_@@_standard_pdf/A-2U_prop }{unicode}{} + %A-3b ============== \prop_new:c { g_@@_standard_pdf/A-3B_prop } \prop_gset_eq:cc @@ -593,11 +614,25 @@ \prop_gput:cnn { g_@@_standard_pdf/A-3B_prop }{name}{pdf/A-3B} \prop_gput:cnn - { g_@@_standard_pdf/A-2B_prop }{year}{2012} + { g_@@_standard_pdf/A-3B_prop }{year}{2012} +\prop_gput:cnn + { g_@@_standard_pdf/A-3B_prop }{level}{3} % embedding files is allowed (with restrictions) \prop_gremove:cn { g_@@_standard_pdf/A-3B_prop } { embed_content} + +%A-3u ============== +\prop_new:c { g_@@_standard_pdf/A-3U_prop } +\prop_gset_eq:cc + { g_@@_standard_pdf/A-3U_prop } + { g_@@_standard_pdf/A-3B_prop } +\prop_gput:cnn + { g_@@_standard_pdf/A-3U_prop }{name}{pdf/A-3U} +\prop_gput:cnn + { g_@@_standard_pdf/A-3U_prop }{conformance}{U} +\prop_gput:cnn + { g_@@_standard_pdf/A-3U_prop }{unicode}{} % \end{macrocode} % \end{variable} % diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdfmeta.pdf b/macros/latex/contrib/pdfmanagement-testphase/l3pdfmeta.pdf index 7b8fdcea93..c6d4c7107b 100644 Binary files a/macros/latex/contrib/pdfmanagement-testphase/l3pdfmeta.pdf and b/macros/latex/contrib/pdfmanagement-testphase/l3pdfmeta.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdftools.dtx b/macros/latex/contrib/pdfmanagement-testphase/l3pdftools.dtx index 76368fc475..edffcde521 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/l3pdftools.dtx +++ b/macros/latex/contrib/pdfmanagement-testphase/l3pdftools.dtx @@ -53,7 +53,7 @@ % }^^A % } % -% \date{Version 0.95d, released 2021-05-14} +% \date{Version 0.95e, released 2021-06-14} % % \maketitle % \begin{documentation} @@ -215,7 +215,7 @@ % % \begin{macrocode} %<*header> -\ProvidesExplPackage{l3pdftools}{2021-05-14}{0.95d} +\ProvidesExplPackage{l3pdftools}{2021-06-14}{0.95e} {candidate commands for l3pdf---LaTeX PDF management testphase bundle} % % \end{macrocode} @@ -346,6 +346,7 @@ \exp_not:N \str_replace_all:Nnn #2 {\c_percent_str 2C} {,} \exp_not:N \str_replace_all:Nnn #2 {\c_percent_str 3B} {;} \exp_not:N \str_replace_all:Nnn #2 {\c_percent_str 3D} {=} + \exp_not:N \str_replace_all:Nnn #2 {\c_percent_str 3F} {?} \exp_not:N \str_replace_all:Nnn #2 {\c_percent_str 30} {0} \exp_not:N \str_replace_all:Nnn #2 {\c_percent_str 31} {1} \exp_not:N \str_replace_all:Nnn #2 {\c_percent_str 32} {2} diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdftools.pdf b/macros/latex/contrib/pdfmanagement-testphase/l3pdftools.pdf index 4df0731176..497b9f5a39 100644 Binary files a/macros/latex/contrib/pdfmanagement-testphase/l3pdftools.pdf and b/macros/latex/contrib/pdfmanagement-testphase/l3pdftools.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdfxform.dtx b/macros/latex/contrib/pdfmanagement-testphase/l3pdfxform.dtx index 25465bdcb0..3508e2b25b 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/l3pdfxform.dtx +++ b/macros/latex/contrib/pdfmanagement-testphase/l3pdfxform.dtx @@ -52,7 +52,7 @@ % }^^A % } % -% \date{Version 0.95d, released 2021-05-14} +% \date{Version 0.95e, released 2021-06-14} % % \maketitle % \begin{documentation} @@ -133,7 +133,7 @@ % \begin{macrocode} %<@@=pdf> %<*header> -\ProvidesExplPackage{l3pdfxform}{2021-05-14}{0.95d} +\ProvidesExplPackage{l3pdfxform}{2021-06-14}{0.95e} {command to create xforms (beta)---LaTeX PDF management testphase bundle} % % \end{macrocode} diff --git a/macros/latex/contrib/pdfmanagement-testphase/l3pdfxform.pdf b/macros/latex/contrib/pdfmanagement-testphase/l3pdfxform.pdf index 8ff3c6f2d5..4b6d7ee999 100644 Binary files a/macros/latex/contrib/pdfmanagement-testphase/l3pdfxform.pdf and b/macros/latex/contrib/pdfmanagement-testphase/l3pdfxform.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/ltdocinit.dtx b/macros/latex/contrib/pdfmanagement-testphase/ltdocinit.dtx index 4d6974eefe..d8e85c5e4c 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/ltdocinit.dtx +++ b/macros/latex/contrib/pdfmanagement-testphase/ltdocinit.dtx @@ -51,7 +51,7 @@ % }^^A % } % -% \date{Version 0.95d, released 2021-05-14} +% \date{Version 0.95e, released 2021-06-14} % % \maketitle % \begin{documentation} @@ -103,10 +103,13 @@ % \item[\texttt{lang}] to set the Lang entry in the Catalog. % E.g. \texttt{lang=de-DE}. The initial value is |en-US| % \item[\texttt{pdfstandard}] Choice key to set the pdf standard. -% Currently |A-1b|, |A-2b| and |A-3b| are accepted as -% values. The underlying code to ensure the requirements (as far as they +% Currently |A-1b|, |A-2b|, |A-2u|, |A-3b| and |A-3u| are accepted as +% values. The casing is irrelevant, |a-1b| works too. +% The underlying code to ensure the requirements (as far as they % can be ensured) is incomplete, but a color profile is included and the -% /OutputIntent is set. More information can be found in the documentation +% /OutputIntent is set. The |u| variants for example do not force unicode, +% but they will pass the information to hyperref and hyperxmp. +% More information can be found in the documentation % of \pkg{l3pdfmeta}. % \item[\texttt{colorprofiles}] This allows to load icc-colorprofiles. Details % are described in the documentation of \pkg{l3pdfmeta}. @@ -138,7 +141,7 @@ % % \begin{function}{\GetDocumentProperties} % \begin{syntax} -% \cs{AddToDocumentProperties}\Arg{label/property} +% \cs{GetDocumentProperties}\Arg{label/property} % \end{syntax} % Expands to the \meta{value} corresponding to \meta{label/property} % in the container. If \meta{label/property} is missing, @@ -164,7 +167,7 @@ % \begin{macrocode} %<@@=pdfmanagement> %<*header> -\ProvidesExplPackage{ltdocinit}{2021-05-14}{0.95d} +\ProvidesExplPackage{ltdocinit}{2021-06-14}{0.95e} {Initialize document metadata} % % \end{macrocode} @@ -329,7 +332,7 @@ \keys_set:nn {document / metadata} {_pdfstandard=\str_uppercase:n{#1}} } ,_pdfstandard .choices:nn = - {A-1B,A-2B,A-3B} + {A-1B,A-2B,A-2U,A-3B,A-3U} { \prop_if_exist:cT { g__pdfmeta_standard_pdf/#1_prop } { diff --git a/macros/latex/contrib/pdfmanagement-testphase/ltdocinit.pdf b/macros/latex/contrib/pdfmanagement-testphase/ltdocinit.pdf index a7138a39fc..15a76982d1 100644 Binary files a/macros/latex/contrib/pdfmanagement-testphase/ltdocinit.pdf and b/macros/latex/contrib/pdfmanagement-testphase/ltdocinit.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/pdflscape-ltx.sty b/macros/latex/contrib/pdfmanagement-testphase/pdflscape-ltx.sty index 43ac3a7ce9..9fa7a39930 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/pdflscape-ltx.sty +++ b/macros/latex/contrib/pdfmanagement-testphase/pdflscape-ltx.sty @@ -22,9 +22,11 @@ %% This work consists of the main source file pdflscape-ltx.sty %% \NeedsTeXFormat{LaTeX2e} -\ProvidesExplPackage{pdflscape-ltx}{2021-05-14}{0.95d} +\ProvidesExplPackage{pdflscape-ltx}{2021-06-14}{0.95e} {Display of landscape pages in PDF - adaption of pdflscape to the PDFmanagement bundle (testphase)} +\DeclareOption*{\PassOptionsToPackage\CurrentOption{graphics}} +\ProcessOptions \RequirePackage{lscape} % this always turns in the same direction as pdflscape does too. % left and right would need diff --git a/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-firstaid.dtx b/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-firstaid.dtx index 647fd55f93..f2cd31608a 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-firstaid.dtx +++ b/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-firstaid.dtx @@ -51,7 +51,7 @@ % }^^A % } % -% \date{Version 0.95d, released 2021-05-14} +% \date{Version 0.95e, released 2021-06-14} % % \maketitle % \begin{documentation} @@ -67,7 +67,7 @@ % |firstaidoff={name1,name2,...}|. % \begin{macrocode} %<*package> -\ProvidesExplPackage{pdfmanagement-firstaid}{2021-05-14}{0.95d} +\ProvidesExplPackage{pdfmanagement-firstaid}{2021-06-14}{0.95e} {LaTeX PDF management testphase bundle / firstaid-patches} %<@@=pdfmanagement> diff --git a/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-firstaid.pdf b/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-firstaid.pdf index 41b232b735..f9ad37cc81 100644 Binary files a/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-firstaid.pdf and b/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-firstaid.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-testphase.dtx b/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-testphase.dtx index 82dc047ada..01636edb1e 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-testphase.dtx +++ b/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-testphase.dtx @@ -51,7 +51,7 @@ % }^^A % } % -% \date{Version 0.95d, released 2021-05-14} +% \date{Version 0.95e, released 2021-06-14} % % \maketitle % \begin{documentation} @@ -384,7 +384,7 @@ % \begin{macrocode} %<@@=pdf> %<*package> -\ProvidesExplPackage{pdfmanagement-testphase}{2021-05-14}{0.95d} +\ProvidesExplPackage{pdfmanagement-testphase}{2021-06-14}{0.95e} {LaTeX PDF management testphase bundle} \providecommand\IfFormatAtLeastTF{\@ifl@t@r\fmtversion} \IfFormatAtLeastTF{2020-10-01}{}{ @@ -411,7 +411,7 @@ % to allow to set it in the document. % \begin{macrocode} %<*header> -\ProvidesExplFile{pdfmanagement-testphase.ltx}{2021-05-14}{0.95d} +\ProvidesExplFile{pdfmanagement-testphase.ltx}{2021-06-14}{0.95e} {PDF~management~code~(testphase)} % %<*package> diff --git a/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-testphase.ins b/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-testphase.ins index 97db2f066e..e6ab7caa43 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-testphase.ins +++ b/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-testphase.ins @@ -129,7 +129,11 @@ and all files in that bundle must be distributed together. {% \from{l3pdffield.dtx}{package} \from{l3pdffield-checkbox.dtx}{package} + \from{l3pdffield-radiobutton.dtx}{package} \from{l3pdffield-textfield.dtx}{package} + \from{l3pdffield-pushbutton.dtx}{package} + \from{l3pdffield-choice.dtx}{package} + \from{l3pdffield-action.dtx}{package} }% } diff --git a/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-testphase.pdf b/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-testphase.pdf index 2d1700dd49..33a851a4cd 100644 Binary files a/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-testphase.pdf and b/macros/latex/contrib/pdfmanagement-testphase/pdfmanagement-testphase.pdf differ diff --git a/macros/latex/contrib/pdfmanagement-testphase/transparent-ltx.sty b/macros/latex/contrib/pdfmanagement-testphase/transparent-ltx.sty index 4b4030c4b2..be65dc7a52 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/transparent-ltx.sty +++ b/macros/latex/contrib/pdfmanagement-testphase/transparent-ltx.sty @@ -3,7 +3,7 @@ %% a replacement for transparent sty from Heiko Oberdiek %% \NeedsTeXFormat{LaTeX2e}[2020/10/01] -\ProvidesExplPackage{transparent-ltx}{2021-05-14}{0.95d} +\ProvidesExplPackage{transparent-ltx}{2021-06-14}{0.95e} {Transparency with color stacks (replacement for transparent.sty from Heiko Oberdiek)}% \RequirePackage{l3opacity} diff --git a/macros/latex/contrib/pdfmanagement-testphase/xcolor-patches-tmp-ltx.sty b/macros/latex/contrib/pdfmanagement-testphase/xcolor-patches-tmp-ltx.sty index 76aee08fef..2070e1b15e 100644 --- a/macros/latex/contrib/pdfmanagement-testphase/xcolor-patches-tmp-ltx.sty +++ b/macros/latex/contrib/pdfmanagement-testphase/xcolor-patches-tmp-ltx.sty @@ -1,6 +1,6 @@ %% LaTeX2e file `xcolor-patches.sty' %% -\ProvidesPackage{xcolor-patches-tmp-ltx}[2021-05-14 v0.95d patch xcolor for l3color] +\ProvidesPackage{xcolor-patches-tmp-ltx}[2021-06-14 v0.95e patch xcolor for l3color] \@ifundefined{color_set:nn}{\RequirePackage{l3color}}{} \ExplSyntaxOn -- cgit v1.2.3