Überarbeitungsverlauf[Zurück]
Klicke auf Einblenden/Ausblenden von Überarbeitungen 7
Verbesserung, siehe http://tex.stackexchange.com/q/193665/5049

29 Jul '14, 14:21

cgnieder's gravatar image

cgnieder
22.1k253463

Das ist kein Bug von `cleveref` oder `varioref`, sondern ein Fehler im Code, den Du zitierst. Zum einen funktioniert `\cref@gettype` nur, wenn das gesuchte Label existiert, also in der `aux`-Datei vorhanden ist. Der Code testet das aber nicht, daher beim ersten Lauf der Fehler. Zum anderen ändert sich nach `\appendix` der `cref`-Typ des `\chapter`-Zählers von `chapter` auf `appendix`, was der Code nicht abfragt. Ich schlage daher zwei (oder eigentlich drei...) Änderungen an der Definition vor: 1. Testen, ob das entsprechende Label existiert, und `\cref@gettype` nur aufrufen, wenn es das tut. Das vermeidet die Fehlermeldung. 2. In `\reftextfaraway` nicht nur auf `chapter` sondern auch auf `appendix` testen, damit `ab Seite` auch nach dem Aufruf von `\appendix` funktioniert. 3. Statt `\def` `\newcommand` bzw. `\renewcommand` verwenden. Das ist zwar eher Kosmetik, entspricht aber der empfohlenen LaTeX-Syntax. Um die Tests bequem zu machen, lade ich [`etoolbox`][1] statt `ifthen`. Dann teste ich mit \ifcsdef{r@labelname}{wahr}{falsch} \ifcsdef{r@<labelname>}{<wahr>}{<falsch>} ob das Label existiert. [Allerdings könnte das zu Problemen führen, wenn man vor dieser Verwendung von `\vref` ein normales `\ref` aufruft][2], da letzteres das Makro `\r@<label>` als `\relax` zurücklässt, wenn das Label nicht definiert ist und `\relax` für `\ifdef` bzw `\ifcsdef` eine zulässige Definition ist. Du verwendest sowieso schon eine KOMA-Script-Klasse, also kannst Du bequemerweise statt dessen auf \ifundefinedorrelax{r@<labelname>}{<wahr>}{<falsch>} % oder \scr@ifundefinedorrelax{r@<labelname>}{<wahr>}{<falsch>} zurückgreifen. Beide werden vom Paket `scrbase` zur Verfügung gestellt und würden damit auch Anwendern anderer Klassen zur Verfügung stehen. (Die Definition von `\ifundefinedorrelax` könnte grundsätzlich durch eine KOMA-Option verhindert werden, dann stünde aber immer noch `\scr@ifundefinedorrelax` zur Verfügung.) Statt `\ifthenelse{\equal{\curtlabtype}{string}{wahr}{falsch}` `\ifthenelse{\equal{\curtlabtype}{<string>}{<wahr>}{<falsch>}` verwende ich `etoolbox`' \ifdefstring{\curtlabtype}{string}{wahr}{falsch} \ifdefstring{\curtlabtype}{<string>}{<wahr>}{<falsch>} Damit ich auf `chapter` und `appendix` in einem Schritt testen kann, verwende ich außerdem `etoolbox`' `\ifboolexpr{ tests }{wahr}{falsch}`: <tests> }{<wahr>}{<falsch>}`: \ifboolexpr { test {\ifdefstring{\curtlabtype}{chapter}} or test {\ifdefstring{\curtlabtype}{appendix}} } {ab Seite} {auf Seite}% Damit erhalte ich: ![alt text][2] text][3] für folgenden Beispielcode: \documentclass[ paper=a4, fontsize=12pt, ]{scrreprt} \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} \usepackage[ngerman]{babel} \usepackage{blindtext} \usepackage[demo]{graphicx} \usepackage[ngerman]{varioref} %\usepackage{hyperref} \usepackage[ngerman]{cleveref} \usepackage{etoolbox} % Cleveref & Varioref: % für Kapitel `ab Seite' statt `auf Seite' setzen \makeatletter \newcommand*\curtlabtype{} \let\@old@cref@vref\cref@vref \renewcommand*\cref@vref[2]{% \ifcsdef{r@#2}% \scr@ifundefinedorrelax{r@#2}% teste, ob Label `#2' definiert ist {} {\cref@gettype{#2}{\curtlabtype}}% {}% \@old@cref@vref{#1}{#2}% } \vref@addto\extrasngerman{% \renewcommand*\reftextfaraway[1]{% \ifboolexpr { test {\ifdefstring{\curtlabtype}{chapter}} or test {\ifdefstring{\curtlabtype}{appendix}} } {ab Seite} {auf Seite}% ~\pageref{#1}}% } \makeatother \begin{document} \chapter{Chap 1} \label{chapt1} \Blindtext[5] \chapter{Chap 2} \label{chapt2} Ein Test auf \vref{chapt1}. Und hier in den Appendix \vref{test}. Hier auf \vref{chapA}. \Blindtext \appendix \chapter{Chap A}\label{chapA} \begin{figure}[h]% \includegraphics[width=0.5\textwidth]{} \caption{test caption} \label{test} \end{figure} \end{document} [1]: http://www.ctan.org/pkg/etoolbox [2]: http://tex.stackexchange.com/q/193665/5049 [3]: http://texwelt.de/wissen/upfiles/vrefcref.png
Klicke auf Einblenden/Ausblenden von Überarbeitungen 6

02 Jul '14, 22:02

cgnieder's gravatar image

cgnieder
22.1k253463

Das ist kein Bug von `cleveref` oder `varioref`, sondern ein Fehler im Code, den Du zitierst. Zum einen funktioniert `\cref@gettype` nur, wenn das gesuchte Label existiert, also in der `aux`-Datei vorhanden ist. Der Code testet das aber nicht, daher beim ersten Lauf der Fehler. Zum anderen ändert sich nach `\appendix` der `cref`-Typ des `\chapter`-Zählers von `chapter` auf `appendix`, was der Code nicht abfragt. Ich schlage daher zwei (oder eigentlich drei...) Änderungen an der Definition vor. (Oder eigentlich drei...) vor: 1. Testen, ob das entsprechende Label existiert, und `\cref@gettype` nur aufrufen, wenn es das tut. Das vermeidet die Fehlermeldung. 2. In `\reftextfaraway` nicht nur auf `chapter` sondern auch auf `appendix` testen, damit `ab Seite` auch nach dem Aufruf von `\appendix` funktioniert. 3. Statt `\def` `\newcommand` bzw. `\renewcommand` verwenden. Das ist zwar eher Kosmetik, entspricht aber der empfohlenen LaTeX-Syntax. Um die Tests bequem zu machen, lade ich [`etoolbox`][1] statt `ifthen`. Dann teste ich mit \ifcsdef{r@labelname}{wahr}{falsch} ob das Label existiert. Statt `\ifthenelse{\equal{\curtlabtype}{string}{wahr}{falsch}` verwende ich `etoolbox`' \ifdefstring{\curtlabtype}{string}{wahr}{falsch} Damit ich auf `chapter` und `appendix` in einem Schritt testen kann, verwende ich außerdem `etoolbox`' `\ifboolexpr{ tests }{wahr}{falsch}`: \ifboolexpr { test {\ifdefstring{\curtlabtype}{chapter}} or test {\ifdefstring{\curtlabtype}{appendix}} } {ab Seite} {auf Seite}% Damit erhalte ich: ![alt text][2] für folgenden Beispielcode: \documentclass[ paper=a4, fontsize=12pt, ]{scrreprt} \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} \usepackage[ngerman]{babel} \usepackage{blindtext} \usepackage[demo]{graphicx} \usepackage[ngerman]{varioref} %\usepackage{hyperref} \usepackage[ngerman]{cleveref} \usepackage{etoolbox} % Cleveref & Varioref: % für Kapitel `ab Seite' statt `auf Seite' setzen \makeatletter \newcommand*\curtlabtype{} \let\@old@cref@vref\cref@vref \renewcommand*\cref@vref[2]{% \ifcsdef{r@#2}% teste, ob Label `#2' definiert ist {\cref@gettype{#2}{\curtlabtype}}% {}% \@old@cref@vref{#1}{#2}% } \vref@addto\extrasngerman{% \renewcommand*\reftextfaraway[1]{% \ifboolexpr { test {\ifdefstring{\curtlabtype}{chapter}} or test {\ifdefstring{\curtlabtype}{appendix}} } {ab Seite} {auf Seite}% ~\pageref{#1}}% } \makeatother \begin{document} \chapter{Chap 1} \label{chapt1} \Blindtext[5] \chapter{Chap 2} \label{chapt2} Ein Test auf \vref{chapt1}. Und hier in den Appendix \vref{test}. Hier auf \vref{chapA}. \Blindtext \appendix \chapter{Chap A}\label{chapA} \begin{figure}[h]% \includegraphics[width=0.5\textwidth]{} \caption{test caption} \label{test} \end{figure} \end{document} [1]: http://www.ctan.org/pkg/etoolbox [2]: http://texwelt.de/wissen/upfiles/vrefcref.png
Klicke auf Einblenden/Ausblenden von Überarbeitungen 5

02 Jul '14, 20:19

cgnieder's gravatar image

cgnieder
22.1k253463

Klicke auf Einblenden/Ausblenden von Überarbeitungen 4

02 Jul '14, 20:18

cgnieder's gravatar image

cgnieder
22.1k253463

Klicke auf Einblenden/Ausblenden von Überarbeitungen 3

02 Jul '14, 20:17

cgnieder's gravatar image

cgnieder
22.1k253463

Klicke auf Einblenden/Ausblenden von Überarbeitungen 2

02 Jul '14, 20:17

cgnieder's gravatar image

cgnieder
22.1k253463

Klicke auf Einblenden/Ausblenden von Überarbeitungen 1

02 Jul '14, 20:17

cgnieder's gravatar image

cgnieder
22.1k253463