Ausgehend von der Antwort von Clemens auf diese Frage würde ich gerne wissen, warum das folgende Beispiel den Fehler

> Use of \reserved@a doesn't match its
> definition. ...{N} \subset \mathds{Z}
> \subset \mathds{Q}

liefert und wie man den Fehler beheben kann.

Open in Online-Editor
\documentclass[12pt]{beamer}
\usepackage{libertine}
\usepackage[libertine,liby,slantedGreek]{newtxmath}
\usepackage{dsfont}
\usepackage{etoolbox,letltxmacro}

\LetLtxMacro\savedmathds\mathds

\newcommand*\vdssets{}
\forcsvlist{\listadd\vdssets}{N,Q,R}
\renewcommand*\mathds[1]{%
  \ifinlist{#1}{\vdssets}
    {\savedmathds{#1}}
    {#1}%
}

\begin{document}

\[ 1\in \mathds{N} \subset \mathds{Z}  \subset \mathds{Q} \subset \mathds{R} \]

\end{document}

Ziel ist es, dass \mathds nur angewendet wird, wenn das Argument in der definierten Liste \vdssets ist.

Update:

Wenn ich \LetLtxMacro durch \let ersetze, gibt es keine Fehlermeldung.

gefragt 05 Mär '16, 19:50

tom75's gravatar image

tom75
2.2k187884
Akzeptiert-Rate: 57%

bearbeitet 06 Mär '16, 11:03


Die Fehlermeldung ist einer der typischen beim Zerbrechen eines Befehls bei der Expansion. In der Tat hilft es hier auch, den Befehl \mathds robust zu deklarieren.

Open in Online-Editor
\documentclass[12pt]{beamer}
\usepackage{libertine}
\usepackage[libertine,liby,slantedGreek]{newtxmath}
\usepackage{dsfont}
\usepackage{etoolbox,letltxmacro}

%\show\mathds
\LetLtxMacro\savedmathds\mathds
\newcommand*\vdssets{}
\forcsvlist{\listadd\vdssets}{N,Q,R}
\DeclareRobustCommand*\mathds[1]{%
  \ifinlist{#1}{\vdssets}
    {\savedmathds{#1}\relax}
    {#1}%
}

\begin{document}
\[
   %\expandafter\show\csname mathds \endcsname
   1\in \mathds{N} \subset \mathds{Z}  \subset \mathds{Q} \subset \mathds{R} 
\]
\end{document}

Die robuste Deklaration ist auch deshalb sinnvoll, weil der Befehl zuvor bereits robust war, und erst durch die Umdefinierung mit \renewcommand zerbrechlich wird. Dass er robust war, kann man erkennen, wenn man die oben auskommentierte Zeile \show\mathds reaktiviert. Dann erhält man in der log-Datei die Ausgabe:

> \mathds=macro:
->\protect \mathds  .
l.7 \show\mathds
Wann immer die \show\foo als Definition eines Makros \protect \foo . (man beachte die zwei Leerzeichen vor dem Punkt) ausgibt, handelt es sich um ein robust deklarierten Befehl.

Allerdings genügt in diesem Fall auch das nicht. \mathds wird nämlich als Mathe-Alphabeth deklariert. Das führt dazu, dass \mathds (das innere mit dem Leerzeichen am Ende) erst mit dem Laden der Schrift endgültig definiert wird. Man sieht das, indem man die oben auskommentierte Zeile \expandafter\show\csname mathds \endcsname reaktiviert. Die Ausgabe zeigt dann nicht die erwartete neue Definition von \mathds, sondern \select@group \mathds \M@U \U/dsrom/m/n, eine typische Definition für ein Mathe-Alphabet.

Wir müssen nun also zusätzlich dafür sorgen, dass die Umdefinierung erst dann aktiv wird, wenn die Schrift bereits geladen wurde. Die Schrift wird spätestens dann geladen, wenn sie das erste Mal verwendet wird. Um genau dafür zu sorgen, können wir beispielsweise mit \savebox eine Box definieren, die einen beliebigen \mathds-Aufruf enthält. Diese Box können wir danach wieder vergessen, also ist es sinnvoll eine der temporären Boxen von LaTeX dafür zu verwenden, beispielsweise \@tempboxa. Da das Schriftsystem von LaTeX außerdem aber erst innerhalb von \begin{document} endgültig initialisiert wird, ist es sinnvoll, diesen Vorgang mit \AtBeginDocument so lange zu verzögern. Es ergibt sich dann beispielsweise:

Open in Online-Editor
\documentclass[12pt]{beamer}
\usepackage{libertine}
\usepackage[libertine,liby,slantedGreek]{newtxmath}
\usepackage{dsfont}
\usepackage{etoolbox,letltxmacro}

% \show\mathds% Erkennung von \protect-Definition
% \expandafter\show\csname mathds \endcsname% Erkennung der eigentlichen Definition

\newcommand*\vdssets{}
\forcsvlist{\listadd\vdssets}{N,Q,R}
\makeatletter
\AtBeginDocument{% warten bis LaTeX das Font-System initialisiert hat
  \sbox\@tempboxa{$\mathds{}$}% Schrift laden und damit \mathds endgültig definieren
  \LetLtxMacro\savedmathds\mathds% Definition übernehmen
  \DeclareRobustCommand*{\mathds}[1]{% neu (und erneut robust) definieren
    \ifinlist{#1}{\vdssets}%
      {\savedmathds{#1}}%
      {#1}%
  }
}
\makeatother

\begin{document}
\[ 
% \expandafter\show\csname mathds \endcsname% Erneute Erkennung der eigentlichen Definition
  1\in \mathds{N} \subset \mathds{Z}  \subset \mathds{Q} \subset \mathds{R} 
\]
\end{document}

Das führt dann auch wie erwartet zu

so geht es

Tatsächlich würde es jetzt auf den ersten Blick sogar genügen, \mathds beim der Umdefinierung nicht robust zu definieren. Allerdings würde dabei dann \mathds beispielsweise beim Schreiben in die toc-Datei bis hinunter zu \savedmathds expandiert. Bei Veränderung der Liste in \vdssets würden diese Veränderungen also im Inhaltsverzeichnis nicht unmittelbar, sondern erst nach einem zusätzlichen LaTeX-Lauf beachtet. Schon das sollte Grund genug sein, wie im Beispiel die Umdefinierung robust vorzunehmen.

Permanenter link

beantwortet 06 Mär '16, 09:49

saputello's gravatar image

saputello
11.1k154365
Akzeptiert-Rate: 51%

bearbeitet 06 Mär '16, 15:03

Vielen Dank für die Erklärung. Das Ergebnis passt aber noch nicht, denn das Z wird nach wie vor mit Doppelstrich gedruckt.

(06 Mär '16, 11:02) tom75

Ja, das Ganze ist noch viel schlimmer als ich dachte. Siehe meine erweiterte Antwort.

(06 Mär '16, 12:31) saputello

Das klingt kompliziert. Warum geht es mit \let gut? Oder kann es dabei dann andere Nebeneffekte geben?

(06 Mär '16, 13:36) tom75

@tom75: Weil dann \savedmathds direkt zu \protect\mathds (das mit dem Leerzeichen am Ende) wird und \savedmathds (das mit dem Leerzeichen am Ende) gar nicht definiert wird. Nebeneffekte nicht ausgeschlossen. Ja, der Umgang mit robusten Makros ist nicht einfach. Und im Zusammenspiel mit dem LaTeX-Fontsystem wird es nicht einfacher. Da muss ich auch oft probieren und mit \show hantieren, um zu sehen, was passiert.

(06 Mär '16, 15:06) saputello

@saputello: Welche Variante ist die sauberere? Deine Lösung oder einfach \let verwenden?

(06 Mär '16, 15:09) tom75

@tom75: Die sauberste Lösung ist, nicht \mathds umzudefinieren, sondern eine neue Anweisung für sauberes semantisches Markup zu definieren.

(06 Mär '16, 16:40) saputello
Ergebnis 5 von 6 show 1 more comments
Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs fügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×20
×14
×1

gestellte Frage: 05 Mär '16, 19:50

Frage wurde gesehen: 7,304 Mal

zuletzt geändert: 06 Mär '16, 16:40