5

I am working with cleveref in a German document and i need in some cases the genitive of the word given by \cref{}. The problem is, that the German genitive is not equally build for all words, so i need some kind of switch-case. Therefore i want a command \crefgen{}, which works similar to \cref{}, but returns the genitive. I think my code shows pretty well what I am trying to achieve. I am sorry that this example is manly in German, but i did not find a useful English example in reasonable time. Nevertheless, I emphasised the important parts I want to add, so it will be clear, even without understanding German.

\documentclass[ngerman,11pt,a4paper]{scrreprt}

\usepackage{cleveref}
\usepackage{ulem}

\newtheorem{problem}{Problem}
\newtheorem{satz}[problem]{Satz}
\newtheorem{proposition}[problem]{Proposition}

\crefname{problem}{Problem}{Probleme}
\crefname{satz}{Satz}{S{\"a}tze}
\crefname{proposition}{Proposition}{Propositionen}

\newcommand{\crefgen}[1]{
    \def\tempStyle{\namecref{#1}}
    \def\tempProblem{Problem}
    \def\tempSatz{Satz} 
    \ifx\tempStyle\tempProblem{
        \namecref{#1}s \labelcref{#1}       % genitive for Problem
    }\else{
        \ifx\tempStyle\tempSatz{
            \namecref{#1}es \labelcref{#1}  % genitive for Satz
        }\else{
            No genitiv defined              % error if no genitive defined
        }\fi
    }\fi
}

\begin{document}

\begin{problem}\label{prob}
Some Text
\end{problem}
\begin{satz}\label{sat}
Some Text
\end{satz}
\begin{proposition}\label{propo}
Some Text
\end{proposition}

\paragraph{What i want:}
Die L{\"o}sung des Problem\uline{s} \ref{prob}.\\
Die Aussage des Satz\uline{es} \ref{sat}.\\
\uline{No genitiv defined} f{\"u}r Propositionen.

\paragraph{How i want to achieve that:}
Die L{\"o}sung des \verb!\crefgen{prob}!.\\
Die Aussage des \verb!\crefgen{sat}!.\\
\verb!\crefgen{propo}! f{\"u}r Propositionen.

\paragraph{How my command looks like:}
Die L{\"o}sung des \crefgen{prob}.\\
Die Aussage des \crefgen{sat}.\\
\crefgen{propo} f{\"u}r Propositionen.

\end{document}

Output of my code

Sveinung
  • 20,355
moro11
  • 150
  • For a probably powerfull solution, not only abel to handle genitiv, but also dativ and akkusativ as well as other languges (e.g. french)... have a look at frougon's extension xcref of the cleveref package on github. It can be found here. – moro11 Sep 20 '19 at 14:00

1 Answers1

4

Welcome to TeX.SE!

You can do as follows using cleveref's \cref@gettype, some \csname, \edef and a tiny bit of expl3 code for the convenient switch-case statement (\str_case:onF). If a gerund form is requested but hasn't been defined, you'll get a real error message that you can't miss, thanks to \errmessage. Of course, one could insert a fallback string as in your example, but I believe \errmessage is better here.

\documentclass[ngerman]{scrreprt}
\usepackage{babel}
% Without amsthm, your 'satz' and 'proposition' are considered to be of type
% 'problem'... which is indeed a problem!
\usepackage{amsthm}
\usepackage{cleveref}
\usepackage{ulem}
\usepackage{expl3}

\newtheorem{problem}{Problem}
\newtheorem{satz}[problem]{Satz}
\newtheorem{proposition}[problem]{Proposition}

\crefname{problem}{Problem}{Probleme}
\crefname{satz}{Satz}{S{\"a}tze}
\crefname{proposition}{Proposition}{Propositionen}

\makeatletter

% Let's borrow \str_case:onF from expl3 (\cs_set_eq:NN is \let)
\ExplSyntaxOn
\cs_set_eq:NN \mycref@str@oswitch \str_case:onF
\ExplSyntaxOff

\newcommand*{\crefgen}[1]{%
    \cref@gettype{#1}{\mycref@type}% type: problem, satz, proposition...
    \edef\mycref@name{%
      \unexpanded\expandafter\expandafter\expandafter{%
        \csname cref@\mycref@type @name\endcsname}}%
    %
    \mycref@str@oswitch
      {\mycref@name}%
      {%
        {Problem}{Problems}%
        {Satz}{Satzes}%
      }%
      {\errmessage{Gerund form undefined for '\mycref@name'}}%
    ~\labelcref{#1}%
}

\makeatother

\begin{document}

\begin{problem}\label{prob}
Some Text
\end{problem}
\begin{satz}\label{sat}
Some Text
\end{satz}
\begin{proposition}\label{propo}
Some Text
\end{proposition}

\paragraph{What I want:}
Die L{\"o}sung des Problem\uline{s} \ref{prob}.\\
Die Aussage des Satz\uline{es} \ref{sat}.\\
\uline{No genitiv defined} f{\"u}r Propositionen (or rather, throw an error).

\paragraph{How I want to achieve that:}
Die L{\"o}sung des \verb!\crefgen{prob}!.\\
Die Aussage des \verb!\crefgen{sat}!.\\
\verb!\crefgen{propo}! f{\"u}r Propositionen.

\paragraph{How my command looks like:}
Die L{\"o}sung des \crefgen{prob}.\\
Die Aussage des \crefgen{sat}.\\
An error is thrown with \verb!\errmessage! if one uncomments
\verb!\crefgen{propo}!.
%\crefgen{propo} f{\"u}r Propositionen.

\end{document}

Screenshot

frougon
  • 24,283
  • 1
  • 32
  • 55
  • Thank you frougon, this solution is as simply as awesome and exactly what i was looking for. Thanks! – moro11 Aug 27 '19 at 12:02
  • Good to hear. As I understand from your comment, you should probably mark my answer as accepted. I have ideas to generalize this to handle 1) preposition + case (Nom. / Akk. / Dat. / Gen.) + singular/plural + upper/lowercase start (applied to the preposition) combinations 2) pass the stuff to \cref (or variants with C and *) so it can compress multiple references. Could work for French too, though a bit differently. Base input syntax (reusable for French) could be like... – frougon Aug 27 '19 at 19:18
  • ... \mycref{prep=aus, case=dativ}{some-label} or \mycref{prep=aus, case=dativ, capitalize-first}{some-label}. For French, the case parameter wouldn't be needed and prep could take values like dans, à... This macro could detect the current language and call a language-dependent macro that would assemble the needed things (aus + dativ + feminin → aus der, etc.). The tables would record the gender with each noun, of course. So, thanks to some language-dependent macro, the \mycref could locally redefine the four macros used by \cref for (singular, Singular, plural, Plural)... – frougon Aug 27 '19 at 19:25
  • and pass the list of references as is to \cref. The four macros are \cref@〈type〉@name, \cref@〈type〉@name@plural, \Cref@〈type〉@name and \Cref@〈type〉@name@plural. I think this should work well for German and French. For French, things are a bit different: for each noun, we must store which definite article should be used (le hibou, l'huile, la houle). Then, we can build the needed compounds mechanically: à + l' → a l'; à + le → au; à + la → à la, etc. No cases such as Akkusativ, Dativ, etc. I think all this is doable and not very complicated with expl3. – frougon Aug 27 '19 at 19:31
  • That sounds really good, i was always missing a feature like that in cleverev. I refused to use cleverevmore than one time due to that. For now i am fine with the solution and will stay with it (i am not familiar with expl3) but i will keep it in mined... maybe i have to worke myself into expl3, sounds pritty powerfull – moro11 Aug 27 '19 at 20:39
  • To be more concrete, the main macro could automatically do (after options processing, etc.) something similar to this (which shows that manually defining the four internal macros I mentioned is not even needed). I believe that, for each language, a default preposition (which could be overridden via an option), should be associated to each type (problem, satz, etc.). Maybe it would be nice too to be able to emit references with (a) only the name, or (b) only the definite article + name, or (c) the full combination (preposition + definite article + name). – frougon Aug 28 '19 at 14:30
  • 1
    For those interested, I wrote a package that implements what I described (handling of all German cases, with or without prepositions, article, hyperlinks, capitalization, and using language modules—I wrote one for French and one for German). I need to do polish the doc before publishing and think a bit more about the interface to make sure it is really the best according to my criteria, but it works well for the tests I did. The code with the two language modules I wrote is too large to post in an answer, otherwise I'd probably have offered it for testing. – frougon Sep 15 '19 at 20:00
  • I am interested indeed :-) – moro11 Sep 16 '19 at 21:05
  • 3
    You can try the xcref package available here. In case you don't know how to clone the repository, you can download the latest state of its master branch as a zip file or as a tarball. Read carefully examples/example-ngerman.tex; along with the xcref.pdf file you can obtain with l3build doc after you have downloaded the source code, it should answer most of your questions. – frougon Sep 19 '19 at 09:00
  • If you think the document-level interface (API) can be improved, please suggest how. Improvements to the language-specific data are also most welcome (see the README.md file). Regarding the keys in the names table for ngerman, I believe satz should be translated to English for consistency with the other keys. How would you translate it (I assume this is not simply “sentence” in a mathematical context)? – frougon Sep 19 '19 at 23:12
  • Satz has no real corresponding translation in englisch (in am mathematical context). But i would translate it with theorem. For example Riesz representation theorem in german Rieszscher Darstellungssatz or Bolzano–Weierstrass theorem in german Satz von Bolzano-Weierstraß . – moro11 Sep 20 '19 at 13:48
  • For my thesis i am writing right now i wont be able to is use it / test it as time is running out. But i had a first look at it... i am really impressed! As soon as i have time to experiment with it i will do that for sure. – moro11 Sep 20 '19 at 13:54
  • Understood about your thesis, and thanks for the precisions concerning Satz. In order to keep it available and distinct from Theorem, the reference type should thus remain as satz, I'd say. Maybe all predefined reference types should also be in local language without accents, for the same reason. That's ugly, but maybe less than language inconsistency... Currently, I'm improving the API a bit (the convenience wrappers will be available without needing \AtBeginDocument and entries can be defined individually as in \xcreffrenchSetNamesTableEntry{section}{\\a}{la}{section}{sections}`) – frougon Sep 20 '19 at 14:34
  • My German lessons are far away. Should I say “Diese „Dinge“ werden mit xcref in der Sektion 3 angegeben“ (I mean “referenced”), or the same with “in die Sektion 3”, or just “in Sektion 3”? The first two would arrange me for an example I'd like to add. If the latter, well... I would need a different example or implement a new form for German, which doesn't exist in French: preposition + noun (without any article). Luckily, I already implemented the various forms as language-specific... – frougon Sep 20 '19 at 22:41
  • Or maybe rather Abschnitt, according to babel/\cref? – frougon Sep 21 '19 at 09:51
  • I would probably go with "in Abschnitt 3". The formulation "in dem Abschnitt" is technically not wrong, but the article "dem" is not necessary and sounds overcomplicated. Also i would prefer "Abschnitt" over "Sektion". – moro11 Sep 21 '19 at 13:45
  • Thanks for the precision. This seems to justify adding a prep+noun form for ngerman (I'm going to replace name with noun in the form values). But this brings a new question: with this form, is it necessary to know the case (nominative, accusative, etc.)? I say this because so far, it is an error if the case can't be determined (either implicitly via \l_@@_ngerman_case_for_prep_prop or explicitly). I suspect that two forms might be invariable with respect to the case: noun (currently called name) and this not-yet-implemented prep+noun. Can you confirm? Of course, users... – frougon Sep 21 '19 at 15:03
  • could do without prep+noun by hardcoding the preposition in the text, but if I add it, the preposition can be explicitly chosen or implicitly determined as the default preposition associated to the reference type (see \g_@@_ngerman_names_prop). Assuming this concept of a default preposition associated to each reference type makes sense, adding the prep+noun form would thus bring a little advantage. – frougon Sep 21 '19 at 15:06
  • Honestly, i am not to good in german grammar, even though it is my mother tongue... its just to complicated ^^. But the case is still relvant, it would be "In Abschnitt 3 wurde XY gezeigt" englisch "we saw in section 3 XY", but "die Aussage des Abschnittes 3 lässt sich zusammenfassen" englisch "the statement of the section 3 can be summarized". – moro11 Sep 22 '19 at 16:54
  • ... i think i did not get your qestion right, did i? – moro11 Sep 22 '19 at 17:08
  • is there some kind of discussion ability in github? If so, maybe this would be more convenient thant spamming this on with comments – moro11 Sep 22 '19 at 17:12
  • You're right about the spamming, and also about the fact that you didn't get my question (I think), because the sentences you proposed don't say what I want, AFAICT. This is not very important, though. For now, I've pushed the sentence mostly in English as “Just to show the effect of our call to \xcrefngermanSetNamesTableEntry: the items from section 1 will be referenced with xcref in der Sektion 3 or durch die Sektion 3” (I could replace Sektion with Abschnitt, right). It probably sounds weird but demonstrates that \xcrefngermanSetNamesTableEntry did its work. More important is... – frougon Sep 22 '19 at 17:52
  • 1
    ... the question I asked here. For followups, you can find my email address in xcref.dtx (look for mailto:). – frougon Sep 22 '19 at 17:53