[latex3-commits] [git/LaTeX3-latex3-latex2e] keys: Add code from l3keys2e as ltkeys (6ba855b2)

Joseph Wright joseph.wright at morningstar2.co.uk
Fri Jul 23 10:26:45 CEST 2021


Repository : https://github.com/latex3/latex2e
On branch  : keys
Link       : https://github.com/latex3/latex2e/commit/6ba855b29d83f6e2a7e8346e2e4fc7763d9c3b59

>---------------------------------------------------------------

commit 6ba855b29d83f6e2a7e8346e2e4fc7763d9c3b59
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date:   Fri Jul 23 09:26:45 2021 +0100

    Add code from l3keys2e as ltkeys
    
    Currently no documentation: where should this go?
    
    New 'LaTeX2e' interfaces to be added later.


>---------------------------------------------------------------

6ba855b29d83f6e2a7e8346e2e4fc7763d9c3b59
 base/changes.txt      |   5 +
 base/doc/source2e.tex |   2 +
 base/format.ins       |   1 +
 base/ltkeys.dtx       | 276 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 284 insertions(+)

diff --git a/base/changes.txt b/base/changes.txt
index f666bec5..5d385b04 100644
--- a/base/changes.txt
+++ b/base/changes.txt
@@ -6,6 +6,11 @@ completeness or accuracy and it contains some references to files that
 are not part of the distribution.
 ================================================================================
 
+2021-07-23  Joseph Wright  <joseh.wright at morningstar2.co.uk>
+
+	* ltkeys.dtx:
+	 New file to replace l3keys2e
+
 2021-07-20  Phelype Oleinik  <phelype.oleinik at latex-project.org>
 
 	* ltcmdhooks.dtx:
diff --git a/base/doc/source2e.tex b/base/doc/source2e.tex
index abe8c1aa..b185db28 100644
--- a/base/doc/source2e.tex
+++ b/base/doc/source2e.tex
@@ -326,6 +326,8 @@ page_precedence "rnaA"
 
  \DocInclude{ltclass}  % Package & Class interface
 
+ \DocInclude{ltkeys}  % Keyval options (L3 module)
+
  \DocInclude{ltfilehook}  % Hook management for files (L3 module)
 
  \DocInclude{ltshipout}% \shipout redefinition (L3 module)
diff --git a/base/format.ins b/base/format.ins
index eece2f57..527844d7 100644
--- a/base/format.ins
+++ b/base/format.ins
@@ -203,6 +203,7 @@ the system are in the document `cfgguide.tex'.
           \from{ltbibl.dtx}{2ekernel}
           \from{ltpage.dtx}{2ekernel}
          \from{ltclass.dtx}{2ekernel,tracerollback}
+          \from{ltkeys.dtx}{2ekernel}        % L3 layer module
           \from{ltfilehook.dtx}{2ekernel}       % L3 layer module
           \from{ltshipout.dtx}{2ekernel}        % L3 layer module
           \from{ltoutput.dtx}{2ekernel}
diff --git a/base/ltkeys.dtx b/base/ltkeys.dtx
new file mode 100644
index 00000000..bef81ab9
--- /dev/null
+++ b/base/ltkeys.dtx
@@ -0,0 +1,276 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2009,2011-2021 The LaTeX Project
+%
+% This file is part of the LaTeX base system.
+% -------------------------------------------
+%
+% It may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3c
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+%    https://www.latex-project.org/lppl.txt
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2008 or later.
+%
+% This file has the LPPL maintenance status "maintained".
+%
+% The list of all files belonging to the LaTeX base distribution is
+% given in the file `manifest.txt'. See also `legal.txt' for additional
+% information.
+%
+% The list of derived (unpacked) files belonging to the distribution
+% and covered by LPPL is defined by the unpacking scripts (with
+% extension .ins) which are part of the distribution.
+%
+% \fi
+%
+% \iffalse
+%
+%%% From File: ltkeys.dtx
+%
+%    \begin{macrocode}
+\def\ltcmdversion{v1.0f}
+\def\ltcmddate{2021-06-04}
+%    \end{macrocode}
+%
+%<*driver>
+% \fi
+\ProvidesFile{ltcmd.dtx}
+  [\ltcmddate\space \ltcmdversion\space
+   LaTeX Kernel (Document commands)]
+% \iffalse
+\documentclass{l3doc}
+\GetFileInfo{ltcmd.dtx}
+\title{\filename}
+\date{\filedate}
+\author{Frank Mittelbach, Chris Rowley, David Carlisle, \LaTeX{} Project Team}
+\begin{document}
+  \maketitle
+  \DocInput{ltcmd.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \StopEventually{}
+%
+%    \begin{macrocode}
+%<@@=keys>
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<*2ekernel|latexrelease>
+\ExplSyntaxOn
+%<latexrelease>\NewModuleRelease{2020/10/01}{ltcmd}
+%<latexrelease>                 {Document~command~parser}%
+%    \end{macrocode}
+%
+% Non-standard variants.
+%    \begin{macrocode}
+\cs_generate_variant:Nn \clist_put_right:Nn { Nv }
+\cs_generate_variant:Nn \keys_if_exist:nnT  { nx }
+\cs_generate_variant:Nn \keys_if_exist:nnTF { nx }
+%    \end{macrocode}
+%
+% \begin{macro}{\l_@@_options_clist}
+%   A single list is used for all options, into which they are collected
+%   before processing.
+%    \begin{macrocode}
+\clist_new:N \l_@@_options_clist
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_@@_process_class_bool}
+%   A flag to indicate that class options should be processed for
+%   packages.
+%    \begin{macrocode}
+\bool_new:N \l_@@_process_class_bool
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_options:n}
+%   The main function calls functions to collect up the global and local
+%   options into \cs{l_@@_kernel_options_clist} before calling the
+%   underlying functions to actually do the processing. So that a suitable
+%   message is produced if the option is unknown, the special
+%   \texttt{unknown} key is set if it does not already exist for the
+%   current module.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_options:n #1
+  {
+    \clist_clear:N \l_@@_options_clist
+    \@@_options_global:n {#1}
+    \@@_options_local:
+    \keys_if_exist:nnF {#1} { unknown }
+      {
+        \keys_define:nn {#1}
+          {
+            unknown .code:n =
+              {
+                \msg_error:nnxx { keys } { option-unknown }
+                  { \l_keys_key_str } { \@currname }
+              }
+          }
+        \AtEndOfPackage
+          { \keys_define:nn {#1} { unknown .undefine: } }
+      }
+    \clist_map_inline:Nn \l_@@_options_clist
+      {
+        \tl_set:Nn \CurrentOption {##1}
+        \keys_set:nn {#1} {##1}
+      }
+    \AtEndOfPackage { \cs_set_eq:NN \@unprocessedoptions \scan_stop: }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_options_global:n}
+%   Global (class) options are handled differently for \LaTeXe{} packages
+%   and classes. Hence this function is essentially a check on the current
+%  file type. The initial test is needed as \LaTeXe{} allows variables to
+%   be equal to \cs{scan_stop:}, which is forbidden in \pkg{expl3} code.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_options_global:n #1
+  {
+    \cs_if_eq:NNF \@classoptionslist \scan_stop:
+      {
+        \cs_if_eq:NNTF \@currext \@clsextension
+          { \@@_options_class:n {#1} }
+          {
+            \bool_if:NT \l_@@_process_class_bool
+             { \@@_options_package:n {#1} }
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_options_class:n}
+%   For classes, each option (stripped of any content after |=|)
+%   is checked for existence as a key. If found, the option is added to
+%   the combined list for processing. On the other hand, unused options
+%   are stored up in \cs{@unusedoptionlist}. Before any of that, though,
+%   there is a simple check to see if there is an |unknown| key. If there
+%   is, then \emph{everything} will match and the mapping can be skipped.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_options_class:n #1
+  {
+    \cs_if_free:cF { opt@ \@currname . \@currext }
+      {
+        \keys_if_exist:nnTF {#1} { unknown }
+          {
+            \clist_put_right:Nv \l_@@_options_clist
+              { opt@ \@currname . \@currext }
+          }
+          {
+            \clist_map_inline:cn { opt@ \@currname . \@currext }
+              {
+                \keys_if_exist:nxTF {#1} { \@@_latexe_remove_equals:n {##1} }
+                  { \clist_put_right:Nn \l_@@_options_clist {##1} }
+                  { \clist_put_right:Nn \@unusedoptionlist {##1} }
+              }
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_options_package:n}
+%   For global options when processing a package, the tasks are slightly
+%   different from those for a class. The check is the same, but here
+%   there is nothing to do if the option is not applicable. Each valid
+%   option also needs to be removed from \cs{@unusedoptionlist}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_options_package:n #1
+  {
+    \clist_map_inline:Nn \@classoptionslist
+      {
+        \keys_if_exist:nxT {#1} { \@@_remove_equals:n {##1} }
+          {
+            \clist_put_right:Nn \l_@@_options_clist {##1}
+            \clist_remove_all:Nn \@unusedoptionlist {##1}
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_options_local:}
+%   If local options are found, the are added to the processing list.
+%   \LaTeXe{} stores options for each file in a macro which may or may not
+%   exist, hence the need to use \cs{cs_if_exist:c}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_options_local:
+  {
+    \cs_if_eq:NNF \@currext \@clsextension
+      {
+        \cs_if_exist:cT { opt@ \@currname . \@currext }
+          {
+            \exp_args:NNc \clist_put_right:NV \l_@@_options_clist
+              { opt@ \@currname . \@currext }
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_remove_equals:n}
+% \begin{macro}{\@@_remove_equals:w}
+%   As the name suggests, this is a simple function to remove an equals
+%   sign from the input. This is all wrapped up in an \texttt{n} function
+%   so that there will always be a sign available.
+%    \begin{macrocode}
+\cs_new:Npn \@@_remove_equals:n #1
+  { \@@_remove_equals:w #1 = \s_@@_stop }
+\cs_new:Npn \@@_remove_equals:w #1 = #2 \s_@@_stop { \exp_not:n {#1} }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ProcessKeysOptions}
+% \begin{macro}{\ProcessKeysPackageOptions}
+%   The user macro are simply wrappers around the internal process. In
+%   contrast to other similar packages, the module name is always required
+%   here.
+%    \begin{macrocode}
+\cs_new_protected:Npn \ProcessKeysOptions #1
+  {
+    \bool_set_true:N \l_@@_process_class_bool
+    \@@_options:n {#1}
+  }
+\cs_new_protected:Npn \ProcessKeysPackageOptions #1
+  {
+    \bool_set_false:N \l_@@_process_class_bool
+    \@@_options:n {#1}
+  }
+\@onlypreamble \ProcessKeysOptions
+\@onlypreamble \ProcessKeysPackageOptions
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% One message to give.
+%    \begin{macrocode}
+\msg_new:nnnn { keys } { option-unknown }
+  { Unknown~option~'#1'~for~package~#2. }
+  {
+    LaTeX~has~been~asked~to~set~an~option~called~'#1'~
+    but~the~#2~package~has~not~created~an~option~with~this~name.
+  }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{0000/00/00}{ltcmd}%
+%<latexrelease>                 {Document~command~parser}%
+%<latexrelease>\EndModuleRelease
+\ExplSyntaxOff
+%</2ekernel|latexrelease>
+%    \end{macrocode}
+%
+% We need to stop DocStrip treating |@@| in a special way at this point.
+%    \begin{macrocode}
+%<@@=>
+%    \end{macrocode}
+%
+% \Finale
+





More information about the latex3-commits mailing list.