\usepackage[opt]{mypkg} Opt. an \RequirePackage{paket} geben

Redefinition von Makros, Definition eigener Befehle sowie neuer Umgebungen


Benutzeravatar
iTob
Forum-Meister
Forum-Meister
Beiträge: 1221
Registriert: Mo 19. Apr 2010, 22:19
Kontaktdaten:

\usepackage[opt]{mypkg} Opt. an \RequirePackage{paket} geben

Beitrag von iTob »

Hallo :-)

ich versuche gerade, mir ein eigenes Paket zu bauen und habe eine Frage zu den Optionen:
[Minimalbeispiel am Ende des Codes...]
Ich würde gerne alle Optionen der in mein Paket eingebundenen Pakete mit
\usepackage[hier alle Optionen]{mypkg} % Befehl in der Präambel von test.tex
aufrufen können.
Das ist mir zum teil auch schon gelungen durch
\DeclareOptions*{\PassOptionsToPackage{\CurrentOption}{paket1}} % Befehl in mypkg.sty
wobei paket1 mit
\RequirePackage[optionen]{paket1} % Befehl in mypkg.sty
aufgerufen wird und alle Optionen annimmt, die ich mypgk in test.tex und paket1 in mypgk.sty übergebe. Dazu muss ich auch die Optionen, die ich mir nicht selbst ausgedachte habe, sondern der Entwickler von paket1 nicht erneut mit
\DeclareOption{...}{...}
erzeugen, sondern kann diese einfach ändern. Soweit so schön, aber jetzt stoße ich auf zwei Probleme:

Problem 1: Wenn ich jetzt – mal angenommen ich (als Fremdanwender) wüsste nicht, dass mypkg paket1 lädt – in test.tex mit
\usepackage[opt]{paket1}
das Paket so zusagen nochmal einbinde, führt das zu der Fehlermeldung:
! LaTeX Error: Missing \begin{document}.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              
                                                  
l.13 \usepackage
                [%
? 
! You can't use `macro parameter character #' in horizontal mode.
\in@ #1#2->\def \in@@ ##1#1##
                             2##3\in@@ {\ifx \in@ ##2\in@false \else \in@tru...
l.13 \usepackage
                [%
? 
! You can't use `macro parameter character #' in horizontal mode.
\in@ #1#2->\def \in@@ ##1#1##2##
                                3\in@@ {\ifx \in@ ##2\in@false \else \in@tru...
l.13 \usepackage
                [%
? 
! Extra \else.
<argument> ...tput-decimal-marker=|,}\ifin@ \else 
                                                  \let \reserved@a \@secondo...
l.13 \usepackage
                [%
? 
! Extra \fi.
\@for ... \@forloop #2,\@nil ,\@nil \@@ #1{#3}\fi 
                                                  
l.13 \usepackage
                [%
? 

! LaTeX Error: Option clash for package siunitx.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              
                                                  
l.13 \usepackage
                [%
? 
(./test.aux) [1] (./test.aux) )
Output written on test.dvi (1 page, 484 bytes).
Transcript written on test.log.
nicht. Statt dessen meldet paket2, dass es eine Option nicht kennt – klar, wenn diese zu paket1 gehört. In meinem Fall beschwert sich komischer Weise paket1 aber nicht über Optionen, die zu paket2 gehören. Konkret geht es um die Pakete lcg (=2) und siunitx (=1).

So und hier das Minimalbeispiel:
\begin{filecontents*}{mypkg.sty}
%%%%% Kenndaten
\ProvidesPackage{mypkg}[2010/08/12]
\NeedsTeXFormat{LaTeX2e}[2009/01/01]
%%%%% Initialisierung
%%%%% Deklarieren von Optionen
\DeclareOption{noautosolution}{\setboolean{@utosol}{false}} % neue Option, mit der das Anhängen der Lösung verhindert wird
\DeclareOption*{% 
	\PassOptionsToPackage{\CurrentOption}{siunitx} % Reicht undefinierte Optionen an siunitx weiter, hat keine Probleme mit lcg-Optionen und unbekannten Optionen [Problem 2]
%	\PassOptionsToPackage{\CurrentOption}{lcg} % Sollte unbekannte Optionen an lcg weitergeben, macht aber Probleme mit siunitx-Optionen [Problem 2]
}
%%%%% Ausführen von Optionen
\ProcessOptions
%%%%% Laden von Paketen
\RequirePackage[
	output-decimal-marker = {|} % Hier lassen sich die Optionen ebefalls setzen
]{siunitx}
\RequirePackage[%
	first=4, % Hier lassen sich die Optionen setzten
	last = 6
]{lcg}
%%%%% Haupteil
% keine Definitionen für dieses Bsp...
\end{filecontents*}

\documentclass[11pt,a4paper]{scrartcl}
\usepackage[latin1]{inputenc}
\usepackage[%
	noautosolve, % Option für mypkg
	output-decimal-marker = {;}, % Option für siunitx
	first=0, % Option für lcg
	last=3, % Option für lcg
	dfggjh, % völlig frei  erfunden, allenn Paketen unbekannt
]{mypkg}
\usepackage[%
	%output-decimal-marker = {*}, % Hier lassen sich die Optionen nicht setzten [Problem 1]
]{siunitx}
\usepackage[%
	%first=7, % Hier lassen sich die Optionen nicht setzten [Problem 1]
	%last=10
]{lcg}
\sisetup{output-decimal-marker = {!}} % Setzen von Optionen mit diesem Befehl geht, an dieser Stelle letzte Definition, so dass ! verwendet wird
\begin{document}
\section*{Pakettest}
Reiner num-Befehl: \num{2.35}

num-Befehl mit in Befehlsoption gesetztem Dezimalmarker
\num[output-decimal-marker  = {,}]{1.45} % hier lässt sich die Option auch setzten, wodurch ! noch mal durch , ersetzt wird
\end{document}
Vielen Dank und Grüße
Tobi

Benutzeravatar
iTob
Forum-Meister
Forum-Meister
Beiträge: 1221
Registriert: Mo 19. Apr 2010, 22:19
Kontaktdaten:

Beitrag von iTob »

Gibt es dazu wirklich keine Lösung? Kann doch nicht sein...

Ich bin inzwischen – danke KOMAs Buch – auf die Idee gekommen, mit
\AfterPackage{paket}{%Anweisungen
  \setboolean{paketgeladen}{true}
}
eine Art if-ABfrage zu Basteln, ob ein Paket durch den Nutzer geladen wurde und das dann nicht durch's Paket laden zu lassen, aber glücklich bin ich mit dieser Lösung nicht, weil sie mir eher unsauber erscheint.
Außerdem müsste dann mypkg vor allen anderen Paketen geladen werden oder (KOMA)?

LG
Tobi

Schweinebacke

Beitrag von Schweinebacke »

option clash gibt es genau dann, wenn ein Paket mehrfach mit unterschiedlichen Optionen geladen werden. Es tritt nicht auf, wenn Pakete ohne Optionen geladen werden. Du solltest also nach Möglichkeit in Deinem Paket die anderen Pakete ohne Optionen laden und stattdessen ggf. die Optionen zuvor per \PassOptionsToPackage an das Paket schicken.

Benutzeravatar
iTob
Forum-Meister
Forum-Meister
Beiträge: 1221
Registriert: Mo 19. Apr 2010, 22:19
Kontaktdaten:

Beitrag von iTob »

Ah, danke, jetzt funktioniert es.

Für alle, die dieses Problem auch noch mal haben, hier eine »Zusammenfassung«:

In eigenen Paketen die Pakete mit
% Zeile in mypkg.sty
\RequirePackage{fremdpaket}% ohne Optionen
(aber ohne die Angabe von Optionen) laden.
Benötigte Optionen innerhalb des eigenen Paketes über den Befehl
% Zeile in mypkg.sty
\PassOptionsToPackage{Liste der Optionen}{fremdpaket}
an die eingebundenen Pakete weitergeben.

Der Anwender hat dann die Möglichkeit, die Pakete selbst mit Optionen zu laden, wobei diese Optionen die in mypkg.sty gewählten ggf. überschreiben (zumindest liefert das mein kurzer Test) oder ergänzen (ungestestet – aber nehme ich mal an).
Beim Aufruf von
% Zeile in test.tex
\usepackage[Optionenliste]{mypkg}
können dann nur Optionen übergeben werden, die direkt von mypkg.sty definiert werden. – Was ja auch sinnvoll ist.

Vielen Dank nochmal an Schweinebacke und die Bitte, meine »Zusammenfassung« nötigenfalls zu korrigieren/ergänzen!

Grüße, Tobi

Antworten