texlive[67706] Master/texmf-dist: crefthe (22jul23)

commits+karl at tug.org commits+karl at tug.org
Sat Jul 22 22:19:27 CEST 2023


Revision: 67706
          http://tug.org/svn/texlive?view=revision&revision=67706
Author:   karl
Date:     2023-07-22 22:19:27 +0200 (Sat, 22 Jul 2023)
Log Message:
-----------
crefthe (22jul23)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/crefthe/README.md
    trunk/Master/texmf-dist/doc/latex/crefthe/crefthe-doc.pdf
    trunk/Master/texmf-dist/doc/latex/crefthe/crefthe-doc.tex
    trunk/Master/texmf-dist/tex/latex/crefthe/crefthe.sty

Modified: trunk/Master/texmf-dist/doc/latex/crefthe/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/crefthe/README.md	2023-07-22 20:18:47 UTC (rev 67705)
+++ trunk/Master/texmf-dist/doc/latex/crefthe/README.md	2023-07-22 20:19:27 UTC (rev 67706)
@@ -1,4 +1,4 @@
-<!-- Copyright (C) 2021-2022 by Jinwen XU -->
+<!-- Copyright (C) 2021-2023 by Jinwen XU -->
 
 # crefthe - cross referencing with proper definite articles
 
@@ -45,6 +45,7 @@
 ```latex
 \crefthename{theorem}[le]{théorème}[les]{théorèmes}
 ```
+(*In French*)
 
 Then you can use the command `\crefthe` as follows:
 - `\crefthe[<prep>]{<labels>}`
@@ -54,8 +55,48 @@
 
 > There is also a stared version `\crefthe*` for generating the same text but without hyperlinks.
 
-*For more information, please refer to its documentation.*
+## Regarding German
 
+In German, there are four declensions: nominative (`Nominativ`), genitive (`Genitiv`), dative (`Dativ`) and accusative (`Akkusativ`). For such situation, we introduce the command `\crefthevariantname` to specify the referencing name for the correspond environment. Below is an example of usage:
+```latex
+\crefthevariantname{theorem}
+  {
+    {Satz}{Sätze}
+    , Nominativ = [der]{Satz}[die]{Sätze}
+    , Genitiv   = [des]{Satzes}[der]{Sätze}
+    , Dativ     = [dem]{Satz}[den]{Sätzen}
+    , Akkusativ = [den]{Satz}[die]{Sätze}
+  }
+```
+The first line in the configuration is the default set of names when no variant is specified. It is recommended, though not required.
+
+After this, you may refer to a theorem via
+
+```latex
+\crefthe[<prep>,variant=<declension>]{<label>}
+```
+
+You may also use the shortcuts (`nom.`, `gen.`, `dat.` and `akk.`), such as:
+
+```latex
+\crefthe[<prep>,Nom]{<label>}     \crefthe[<prep>,Nom.]{<label>}
+\crefthe[<prep>,nom]{<label>}     \crefthe[<prep>,nom.]{<label>}
+```
+
+These four are all equivalent and you may choose one to use according to your preference.
+
+> *For more information, please refer to the documentation.*
+
+# Acknowledgement
+
+There are so many people I wish to express my gratitude to during the development of this package, including:
+
+- Patrick Bideault, without whose advice and careful explanation, this package probably would never have been born. Merci !
+
+- Enrico Gregorio, Phelype Oleinik and Joseph Wright (in alphabetical order). They made valuable suggestions in the early development of this package and even edited some of the code themselves.
+
+- Jonathan P. Spratte, without whose help the German support would probably take much longer to complete.
+
 # License
 
 This work is released under the LaTeX Project Public License, v1.3c or later.

Modified: trunk/Master/texmf-dist/doc/latex/crefthe/crefthe-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/crefthe/crefthe-doc.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/crefthe/crefthe-doc.tex	2023-07-22 20:18:47 UTC (rev 67705)
+++ trunk/Master/texmf-dist/doc/latex/crefthe/crefthe-doc.tex	2023-07-22 20:19:27 UTC (rev 67706)
@@ -48,6 +48,7 @@
         crefformat,
         crefthe,crefthename,
         Crefthe,Crefthename,
+        crefthevariantname,Crefthevariantname,
         namecrefthe,namecrefsthe,
         nameCrefthe,nameCrefsthe,
         crefthemark,
@@ -116,12 +117,12 @@
 
 \begin{document}
 
-\def\PackageVersion{2022/09/24}
+\def\PackageVersion{2023/07/22}
 
 \title{\crefthepackage{}\\\smallskip\itshape Cross referencing with proper definite articles}
 \author{Jinwen XU}
 \thanks{Corresponding to: \texttt{\crefthepackage{} \PackageVersion}}
-\date{\TheDate{\PackageVersion}[only-year-month], in Paris}
+\date{\TheDate{\PackageVersion}[only-year-month], in Beijing}
 
 \maketitle
 
@@ -132,7 +133,7 @@
 
 \section{The motivation}
 
-By default, with \textsf{cleveref}'s \lstinline|\cref| to reference theorem-like environments, the names do not contain definite articles. While this might be acceptable for English, it is certainly not good enough for languages such as French, Italian, Portuguese, Spanish, etc. -- in these cases there shall be grammatical errors and would give you a strong feeling that it is machine-generated.
+By default, with \textsf{cleveref}'s \lstinline|\cref| to reference theorem-like environments, the names do not contain definite articles. While this might be acceptable for English, it is certainly not good enough for languages such as French, Italian, Portuguese, Spanish, etc. --- in these cases there shall be grammatical errors and would give you a strong feeling that it is machine-generated.
 
 However, even if we manually add the definite articles to the names, there would still be other problems. As an example, if we define the French names to be:
 
@@ -241,6 +242,38 @@
 
 Voilà !
 
+\section{What about German}
+
+In German, there are four declensions: nominative (\texttt{Nominativ}), genitive (\texttt{Genitiv}), dative (\texttt{Dativ}) and accusative (\texttt{Akkusativ}), making the previously presented mechanism insufficient. For such situation, we introduce the command \lstinline|\crefthevariantname| to specify the referencing name for the correspond environment. Below is an example of usage:
+
+\begin{code}
+\crefthevariantname{theorem}
+  {
+    {Satz}{Sätze}
+    , Nominativ = [der]{Satz}[die]{Sätze}
+    , Genitiv   = [des]{Satzes}[der]{Sätze}
+    , Dativ     = [dem]{Satz}[den]{Sätzen}
+    , Akkusativ = [den]{Satz}[die]{Sätze}
+  }
+\end{code}
+
+The first line in the configuration is the default set of names when no variant is specified. It is recommended, though not required.
+
+After this, you may refer to a theorem via
+
+\begin{code}
+\crefthe[(*\meta{prep}*),variant=(*\meta{declension}*)]{(*\meta{label}*)}
+\end{code}
+
+You may also use the shortcuts (\texttt{nom.}, \texttt{gen.}, \texttt{dat.} and \texttt{akk.}), such as:
+
+\begin{code}
+\crefthe[(*\meta{prep}*),Nom]{(*\meta{label}*)}     \crefthe[(*\meta{prep}*),Nom.]{(*\meta{label}*)}
+\crefthe[(*\meta{prep}*),nom]{(*\meta{label}*)}     \crefthe[(*\meta{prep}*),nom.]{(*\meta{label}*)}
+\end{code}
+
+These four are all equivalent and you may choose one to use according to your preference.
+
 \section{Regarding the upper and lower cases}
 
 As in \textsf{cleveref}, these commands have corresponding uppercased version: \lstinline|\Crefthename|,\linebreak \lstinline|\Crefthe|, \lstinline|\nameCrefthe| and \lstinline|\nameCrefsthe|, similar to \lstinline|\Crefname|, \lstinline|\Cref|, \lstinline|\nameCref|\linebreak and \lstinline|\nameCrefs|, reserved for using at the beginning of a sentence. \lstinline|\Crefthe| (and the name-only relatives) can handle case changing automatically: for example, with \lstinline|\Crefthe[À]{thm1,thm2,prop3}|, you will get something like
@@ -271,17 +304,33 @@
 
 \section{The relationship with \textsf{cleveref}}
 
-\crefthepackage{} loads \textsf{cleveref} automatically and pass related options to it. All its commands, used without optional arguments, degenerate to those in \textsf{cleveref}. For example, \lstinline|\crefthe{...}| is the same as \lstinline|\cref{...}|, and \lstinline|\crefthename| is the same as \lstinline|\crefname| if the definite articles are not specified. That said, you can safely use the command \lstinline|\crefthe| everywhere in your document without causing extra trouble.
+\crefthepackage{} loads \textsf{cleveref} automatically and passes related options to it. All its commands, used without optional arguments, degenerate to those in \textsf{cleveref}. For example, \lstinline|\crefthe{...}|%
+will produce the same result as \lstinline|\cref{...}|, and \lstinline|\crefthename| shall behave the same as \lstinline|\crefname| if the definite articles are not specified. That said, you may safely use the command \lstinline|\crefthe| everywhere in your document without causing extra trouble.
 
-With the package option \packageoption{overwrite}, user commands in \textsf{cleveref} will be replaced by those offered here, thus you can simply write \lstinline|\cref| for \lstinline|\crefthe| -- and similarly with \lstinline|\Cref|, \lstinline|\crefname| and \lstinline|\Crefname|.
+With the package option \packageoption{overwrite}, user commands in \textsf{cleveref} will be replaced by those offered here, thus you can simply write \lstinline|\cref| for \lstinline|\crefthe| --- and similarly with \lstinline|\Cref|, \lstinline|\crefname| and \lstinline|\Crefname|.
 
 
 \clearpage
 
+
+\section{Acknowledgement}
+
+There are so many people I wish to express my gratitude to during the development of this package, including:
+
+\begin{itemize}
+    \item Patrick Bideault, without whose advice and careful explanation, this package would probably never have been born. Merci !
+    \item Enrico Gregorio, Phelype Oleinik and Joseph Wright (in alphabetical order). They made valuable suggestions in the early development of this package and even edited some of the code themselves.
+    \item Jonathan P. Spratte, without whose help the German support would probably take much longer to complete.
+\end{itemize}
+
+
+% \clearpage
+
 \section{Known issues}
 \begin{itemize}
-    \item \crefthepackage{} currently works for French, Italian, Portuguese (European and Brazilian) and Spanish, certainly more would be added to this list.
-    \item The current mechanism does not work for German. The author plans to adopt a more refined approach in later versions in order to support the various situations in German. Meanwhile, you may consider the package \textsf{zref-clever}, which has a much more powerful and sophisticated interface for configuring cross referencing.
+    \item \crefthepackage{} currently works for French, German, Italian, Portuguese (European and Brazilian) and Spanish --- certainly more languages would be added to this list in the future.
+    \item For now, you cannot specify the masculine/masculine/... of words. This means, for instance, that you cannot make the suffix adjective automatically adopted to the word when using \lstinline|\namecref| --- as an example, if you wish to say \textquote{la proposition suivante} (in French), you would have to write the feminine adjective manually. The situation should be improved with the introduction of a new key-value configuration system, which is currently on the todo-list.
+    Meanwhile, you may consider the package \textsf{zref-clever}, which has a much more powerful and sophisticated interface for configuring cross referencing.
     \item The names of theorem-like environments are not provided here, you need to define them by yourself. However, users are encouraged to use the \ProjLib{} toolkit (more specifically, the internal package \textsf{create-theorem}), which already handles everything for you.
 \end{itemize}
 

Modified: trunk/Master/texmf-dist/tex/latex/crefthe/crefthe.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/crefthe/crefthe.sty	2023-07-22 20:18:47 UTC (rev 67705)
+++ trunk/Master/texmf-dist/tex/latex/crefthe/crefthe.sty	2023-07-22 20:19:27 UTC (rev 67706)
@@ -1,5 +1,5 @@
 %%
-%% Copyright (C) 2021-2022 by Jinwen XU
+%% Copyright (C) 2021-2023 by Jinwen XU
 %% ------------------------------------
 %%
 %% This file may be distributed and/or modified under the conditions of
@@ -12,7 +12,7 @@
 \NeedsTeXFormat{LaTeX2e}[2022-06-01]
 \ProvidesExplPackage
   {crefthe}
-  {2022/09/24} {}
+  {2023/07/22} {}
   {Cross referencing with proper definite articles}
 
 \keys_define:nn { crefthe }
@@ -87,20 +87,90 @@
     \__crefthe_cref_general:NNNnnN \c_false_bool #1 #2 { #3 } { #4 } \crefthe_nameCrefs_original:w
   }
 
+\keys_define:nn { crefthe-setting }
+  {
+    , variant       .tl_set:N           = \l__crefthe_variant_tl
+
+    % , nom           .meta:n             = { variant = Nominativ }
+    % , nom.          .meta:n             = { variant = Nominativ }
+    % , Nom           .meta:n             = { variant = Nominativ }
+    % , Nom.          .meta:n             = { variant = Nominativ }
+    % , gen           .meta:n             = { variant = Genitiv   }
+    % , gen.          .meta:n             = { variant = Genitiv   }
+    % , Gen           .meta:n             = { variant = Genitiv   }
+    % , Gen.          .meta:n             = { variant = Genitiv   }
+    % , dat           .meta:n             = { variant = Dativ     }
+    % , dat.          .meta:n             = { variant = Dativ     }
+    % , Dat           .meta:n             = { variant = Dativ     }
+    % , Dat.          .meta:n             = { variant = Dativ     }
+    % , akk           .meta:n             = { variant = Akkusativ }
+    % , akk.          .meta:n             = { variant = Akkusativ }
+    % , Akk           .meta:n             = { variant = Akkusativ }
+    % , Akk.          .meta:n             = { variant = Akkusativ }
+
+    % , unknown       .code:n             = {
+    %                                         \bool_gset_true:N \g__crefthe_has_prep_bool
+    %                                         \tl_set:No \l__crefthe_prep_tl { \l_keys_key_tl }
+    %                                       }
+
+    , unknown       .code:n             = {}
+  }
+
+\bool_new:N \l__crefthe_variant_matched_bool
 \cs_new_protected:Nn \__crefthe_cref_general:NNNnnN
+  % #1 = star or not
+  % #2 = -
+  % #3 = +
+  % #4 = key-value
+  % #5 = label
+  % #6 = original command, such as \crefthe_cref_original:w or \crefthe_Cref_original:w
   {
-    \tl_if_blank:eTF { #4 }
+    \tl_set:Nn \l__crefthe_variant_tl {}
+    \bool_gset_false:N \g__crefthe_has_prep_bool
+    \tl_set:Nn \l__crefthe_prep_tl {}
+
+    \keys_set:nn { crefthe-setting } { #4 }
+
+    % This should actually be part of the keys parsing
+    \clist_map_inline:nn { #4 }
       {
-        \bool_gset_false:N \g__crefthe_has_prep_bool
+        \bool_set_false:N \l__crefthe_variant_matched_bool
+        \str_if_in:nnF { ##1 } { = }
+          {% for keys without values
+            \str_if_eq:VnT \languagename { ngerman }
+              {
+                \str_case:nnT { ##1 }
+                  {
+                    { nom  } { \tl_set:Nn \l__crefthe_variant_tl { Nominativ } }
+                    { nom. } { \tl_set:Nn \l__crefthe_variant_tl { Nominativ } }
+                    { Nom  } { \tl_set:Nn \l__crefthe_variant_tl { Nominativ } }
+                    { Nom. } { \tl_set:Nn \l__crefthe_variant_tl { Nominativ } }
+                    { gen  } { \tl_set:Nn \l__crefthe_variant_tl { Genitiv }   }
+                    { gen. } { \tl_set:Nn \l__crefthe_variant_tl { Genitiv }   }
+                    { Gen  } { \tl_set:Nn \l__crefthe_variant_tl { Genitiv }   }
+                    { Gen. } { \tl_set:Nn \l__crefthe_variant_tl { Genitiv }   }
+                    { dat  } { \tl_set:Nn \l__crefthe_variant_tl { Dativ }     }
+                    { dat. } { \tl_set:Nn \l__crefthe_variant_tl { Dativ }     }
+                    { Dat  } { \tl_set:Nn \l__crefthe_variant_tl { Dativ }     }
+                    { Dat. } { \tl_set:Nn \l__crefthe_variant_tl { Dativ }     }
+                    { akk  } { \tl_set:Nn \l__crefthe_variant_tl { Akkusativ } }
+                    { akk. } { \tl_set:Nn \l__crefthe_variant_tl { Akkusativ } }
+                    { Akk  } { \tl_set:Nn \l__crefthe_variant_tl { Akkusativ } }
+                    { Akk. } { \tl_set:Nn \l__crefthe_variant_tl { Akkusativ } }
+                  } { \bool_set_true:N \l__crefthe_variant_matched_bool }
+              }
+            \bool_if:NF \l__crefthe_variant_matched_bool
+              {
+                \tl_set:Nn \l__crefthe_prep_tl { ##1 }
+              }
+          }
       }
-      {
-        \bool_gset_true:N \g__crefthe_has_prep_bool
-      }
+
     \bool_if:NTF #2
-      { \tl_set:Nn \l__crefthe_prep_once_tl { #4 } }
+      { \tl_set:No \l__crefthe_prep_once_tl { \l__crefthe_prep_tl } }
       {
         \bool_if:NTF #3
-          { \tl_set:Nn \l__crefthe_prep_each_tl { #4 } }
+          { \tl_set:No \l__crefthe_prep_each_tl { \l__crefthe_prep_tl } }
           {
             % \str_set:Nx fully expands \__crefthe_prep_mode: into a string,
             % then \str_case:Vn compares the value of the resulting string:
@@ -107,14 +177,14 @@
             \str_set:Nx \l__crefthe_tmpa_str { \__crefthe_prep_mode: }
             \str_case:Vn \l__crefthe_tmpa_str
               {
-                { - } { \tl_set:Nn \l__crefthe_prep_once_tl { #4 } }
-                { + } { \tl_set:Nn \l__crefthe_prep_each_tl  { #4 } }
+                { - } { \tl_set:No \l__crefthe_prep_once_tl { \l__crefthe_prep_tl } }
+                { + } { \tl_set:No \l__crefthe_prep_each_tl  { \l__crefthe_prep_tl } }
               }
           }
       }
     \group_begin:
     \bool_if:NTF #1
-      { #6 * { #5 } } % here #6 is \crefthe_cref_original:w or \crefthe_Cref_original:w
+      { #6 * { #5 } }
       { #6   { #5 } }
     \group_end:
     \tl_gclear:N \l__crefthe_prep_each_tl
@@ -123,14 +193,15 @@
 % \__crefthe_prep_mode: defines the default mode for supported languages
 \cs_new:Nn \__crefthe_prep_mode:
   {
-    \str_case:Vn \languagename
+    \str_case:VnF \languagename
       {
         {french}        { + }
+        {ngerman}       { - }
         {italian}       { + }
         {spanish}       { - }
         {portuguese}    { + }
         {brazilian}     { + }
-      }
+      } { + }
   }
 
 \NewDocumentCommand \crefthename { m O{} m O{} m }
@@ -143,13 +214,13 @@
     \__crefthe_name_general:nnnnnn { #1 } { #2 } { #3 } { #4 } { #5 } { C }
   }
 
-\cs_new:Npn \crefthe_width_of_space_dim { \tex_fontdimen:D 2 \tex_font:D~plus -\tex_fontdimen:D 3 \tex_font:D~minus -\tex_fontdimen:D 4 \tex_font:D }
+\cs_new:Npn \crefthe_retrieve_space: { \skip_horizontal:n { -\tex_fontdimen:D 2 \tex_font:D~plus -\tex_fontdimen:D 3 \tex_font:D~minus -\tex_fontdimen:D 4 \tex_font:D } }
 
 \cs_new:Nn \crefthe_empty_adjust:n
   {
     \tl_if_blank:nTF { #1 }
       {
-        \skip_horizontal:n { -\crefthe_width_of_space_dim }
+        \crefthe_retrieve_space:
       }
       {
         #1
@@ -157,8 +228,13 @@
   }
 
 \cs_new_protected:Nn \__crefthe_name_general:nnnnnn
+  % #1 = environment name
+  % #2 = singular definite article
+  % #3 = singular name
+  % #4 = plural definite article
+  % #5 = plural name
+  % #6 = c or C
   {
-    % #6 is c or C
     \__crefthe_name_general_do:nnnnnn
       { #1 }
       { \crefthemark { \crefthe_empty_adjust:n { #2 } } }
@@ -183,6 +259,130 @@
       }
   }
 
+\NewDocumentCommand \crefthevariantname { m m }
+  {
+    \crefthe_parse_variant:n { #2 }
+    \crefthe_pass_variant_to:n { \crefthename { #1 } }
+  }
+
+\NewDocumentCommand \Crefthevariantname { m m }
+  {
+    \crefthe_parse_variant:n { #2 }
+    \crefthe_pass_variant_to:n { \Crefthename { #1 } }
+  }
+
+\tl_new:N \l__crefthe_variant_noun_singular_tl
+\tl_new:N \l__crefthe_variant_noun_plural_tl
+\tl_new:N \l__crefthe_variant_article_singular_tl
+\tl_new:N \l__crefthe_variant_article_plural_tl
+\tl_new:N \l__crefthe_variant_default_noun_singular_tl
+\tl_new:N \l__crefthe_variant_default_noun_plural_tl
+\tl_new:N \l__crefthe_variant_default_article_singular_tl
+\tl_new:N \l__crefthe_variant_default_article_plural_tl
+\bool_new:N \l__crefthe_variant_default_bool
+\cs_new_protected:Npn \crefthe_parse_variant:n #1
+  {
+    \tl_clear:N \l__crefthe_variant_noun_singular_tl
+    \tl_clear:N \l__crefthe_variant_noun_plural_tl
+    \tl_clear:N \l__crefthe_variant_article_singular_tl
+    \tl_clear:N \l__crefthe_variant_article_plural_tl
+    \tl_clear:N \l__crefthe_variant_default_noun_singular_tl
+    \tl_clear:N \l__crefthe_variant_default_noun_plural_tl
+    \tl_clear:N \l__crefthe_variant_default_article_singular_tl
+    \tl_clear:N \l__crefthe_variant_default_article_plural_tl
+    \bool_set_false:N \l__crefthe_variant_default_bool
+    \keyval_parse:NNn
+      \__crefthe_parse_variant_default:n
+      \__crefthe_parse_variant_value:nn
+      { #1 }
+  }
+\tl_new:N \l__crefthe_parsed_tl
+\NewDocumentCommand \__crefthe_variant_parser:w { O{} m O{} m }
+  {
+    \tl_if_blank:nTF { #1 }
+      {
+        \tl_set:Nn \l__crefthe_parsed_tl { { \crefthe_retrieve_space: } { #2 } { \crefthe_retrieve_space: } { #4 } }
+      }
+      {
+        \tl_set:Nn \l__crefthe_parsed_tl { { #1 } { #2 } { #3 } { #4 } }
+      }
+    \use_none_delimit_by_q_stop:w
+  }
+\cs_new_protected:Npn \__crefthe_parse_variant_default:n #1
+  {
+    \bool_set_true:N \l__crefthe_variant_default_bool
+    \__crefthe_variant_parser:w #1 \q_stop
+    \tl_set:Nx \l__crefthe_variant_default_article_singular_tl
+      { \tl_item:Nn \l__crefthe_parsed_tl { 1 } }
+    \tl_set:Nx \l__crefthe_variant_default_noun_singular_tl
+      { \tl_item:Nn \l__crefthe_parsed_tl { 2 } }
+    \tl_set:Nx \l__crefthe_variant_default_article_plural_tl
+      { \tl_item:Nn \l__crefthe_parsed_tl { 3 } }
+    \tl_set:Nx \l__crefthe_variant_default_noun_plural_tl
+      { \tl_item:Nn \l__crefthe_parsed_tl { 4 } }
+  }
+\cs_new_protected:Npn \__crefthe_parse_variant_value:nn #1#2
+  {
+    \__crefthe_variant_parser:w #2 \q_stop
+    \tl_put_right:Nx \l__crefthe_variant_article_singular_tl
+      { { \tl_to_str:n { #1 } } { \tl_item:Nn \l__crefthe_parsed_tl { 1 } } }
+    \tl_put_right:Nx \l__crefthe_variant_noun_singular_tl
+      { { \tl_to_str:n { #1 } } { \tl_item:Nn \l__crefthe_parsed_tl { 2 } } }
+    \tl_put_right:Nx \l__crefthe_variant_article_plural_tl
+      { { \tl_to_str:n { #1 } } { \tl_item:Nn \l__crefthe_parsed_tl { 3 } } }
+    \tl_put_right:Nx \l__crefthe_variant_noun_plural_tl
+      { { \tl_to_str:n { #1 } } { \tl_item:Nn \l__crefthe_parsed_tl { 4 } } }
+  }
+
+\cs_new_protected:Npn \crefthe_pass_variant_to:n #1
+  {
+    \use:e
+      {
+        \exp_not:n { #1 }
+        \bool_if:NTF \l__crefthe_variant_default_bool
+          {
+            [
+              \exp_not:n { \str_case:NnF \l__crefthe_variant_tl }
+                { \exp_not:o \l__crefthe_variant_article_singular_tl }
+                { \exp_not:o \l__crefthe_variant_default_article_singular_tl }
+            ]
+            {
+              \exp_not:n { \str_case:NnF \l__crefthe_variant_tl }
+                { \exp_not:o \l__crefthe_variant_noun_singular_tl }
+                { \exp_not:o \l__crefthe_variant_default_noun_singular_tl }
+            }
+            [
+              \exp_not:n { \str_case:NnF \l__crefthe_variant_tl }
+                { \exp_not:o \l__crefthe_variant_article_plural_tl }
+                { \exp_not:o \l__crefthe_variant_default_article_plural_tl }
+            ]
+            {
+              \exp_not:n { \str_case:NnF \l__crefthe_variant_tl }
+                { \exp_not:o \l__crefthe_variant_noun_plural_tl }
+                { \exp_not:o \l__crefthe_variant_default_noun_plural_tl }
+            }
+          }
+          {
+            [
+              \exp_not:n { \str_case:Nn \l__crefthe_variant_tl }
+                { \exp_not:o \l__crefthe_variant_article_singular_tl }
+            ]
+            {
+              \exp_not:n { \str_case:Nn \l__crefthe_variant_tl }
+                { \exp_not:o \l__crefthe_variant_noun_singular_tl }
+            }
+            [
+              \exp_not:n { \str_case:Nn \l__crefthe_variant_tl }
+                { \exp_not:o \l__crefthe_variant_article_plural_tl }
+            ]
+            {
+              \exp_not:n { \str_case:Nn \l__crefthe_variant_tl }
+                { \exp_not:o \l__crefthe_variant_noun_plural_tl }
+            }
+          }
+      }
+  }
+
 \seq_new:N \g__crefthe_already_patched_seq
 
 \cs_new_protected:Nn \crefthe_patch_format:nnnn
@@ -209,7 +409,6 @@
   { format-patch-failed }
   { Failed~to~patch~the~format~"\iow_char:N \\#1"! }
 
-\cs_generate_variant:Nn \text_lowercase:n { V }
 \NewDocumentCommand \crefthemark { m }
   {
     \crefthe_contraction:Ve \l__crefthe_prep_each_tl
@@ -216,12 +415,12 @@
       { \crefthe_contraction:Vn \l__crefthe_prep_once_tl { #1 } }
     \tl_gclear:N \l__crefthe_prep_once_tl
     \tl_gset:Nx \l__crefthe_prep_each_tl
-      { \text_lowercase:V \l__crefthe_prep_each_tl }
+      { \text_lowercase:n { \l__crefthe_prep_each_tl } }
     \str_if_eq:eeF { \str_tail:n { #1 } } { ' } { ~ }
     \bool_gset_false:N \g__crefthe_uppercase_bool
   }
 
-\prg_generate_conditional_variant:Nnn \str_case_e:nn { nv } { T, F, TF }
+\prg_generate_conditional_variant:Nnn \str_case_e:nn { ev } { T, F, TF }
 \cs_new:Nn \crefthe_contraction:nn
   {
     \exp_args:Ne \__crefthe_contraction:nnn
@@ -239,7 +438,7 @@
           {
             \exp_args:Ne \__crefthe_conditional_uppercase:n
               {
-                \str_case_e:nvF { #2~#1 }
+                \str_case_e:evF { #2~#1 }
                   { c_crefthe_contraction_rule_ \languagename _tl }
                   { #2~#1 }
               }
@@ -249,6 +448,7 @@
   }
 \cs_new:Nn \__crefthe_conditional_uppercase:n
   {
+    % \bool_set_false:N \l_text_titlecase_check_letter_bool
     \bool_if:NTF \g__crefthe_uppercase_bool
       { \text_titlecase_first:n }
       { \use:n }
@@ -293,6 +493,25 @@
     { De~le  }     { Du  }
     { De~les }     { Des }
   }
+\tl_const:Nn \c_crefthe_contraction_rule_ngerman_tl
+  {
+    { an~dem  }     { am   }
+    { an~das  }     { ans  }
+    { bei~dem }     { beim }
+    { in~dem  }     { im   }
+    { in~das  }     { ins  }
+    { von~dem }     { vom  }
+    { zu~dem  }     { zum  }
+    { zu~der  }     { zur  }
+    { An~dem  }     { Am   }
+    { An~das  }     { Ans  }
+    { Bei~dem }     { Beim }
+    { In~dem  }     { Im   }
+    { In~das  }     { Ins  }
+    { Von~dem }     { Vom  }
+    { Zu~dem  }     { Zum  }
+    { Zu~der  }     { Zur  }
+  }
 \tl_const:Nn \c_crefthe_contraction_rule_italian_tl
   {
     { a~il   }     { al    }



More information about the tex-live-commits mailing list.