Seite 1 von 1

Umgebung die den Code innerhalb verschluckt

Verfasst: Mo 1. Nov 2010, 19:47
von pospiech
Ich möchte ganze Abschnitte in der Präambel ein und ausschalten können:
\begin{TemplatePdfSection}
\usepackage{...}
....
\end{TemplatePdfSection}
und dachte dabei an diese Befehle
\DefineTemplateSection[enabled]{TemplatePdfSection}
% zusammen mit 
\SetTemplateSection{TemplatePdfSection}{enabled}
die wesentliche Frage ist - wie erzeuge ich eine Umgebung die den Inhalt komplett wegwirft, oder überhaupt nicht beeinflusst?

Probiert habe ich es mit folgendem Code, aber der wirft mir sofort Fehler sobald ich Code in eine Umgebung packe. Das Paket comment ist auch nicht meine erste Wahl, aber das einzige was ich dafür kannte um es zu missbrauchen...
\documentclass[]{article}

%\usepackage[latin1]{inputenc}
%\input{preambel/preambel}

\RequirePackage{ifthen}
\makeatletter
%%% --- basic missing latex code 
\newcommand*{\provideenvironment}{%
  \@ifstar {\@sprovideenvironment}{\@provideenvironment}%
}
\newcommand*{\@sprovideenvironment}[1]{%
  \@ifundefined{#1}{\newenvironment*{#1}}{\@gobbletwo}%
}
\newcommand*{\@provideenvironment}[1]{%
  \@ifundefined{#1}{\newenvironment{#1}}{\@gobbletwo}%
}
\makeatother

\RequirePackage{comment}

% \DefineTemplateSection[enabled]{TemplatePdfSection}
\newcommand{\DefineTemplateSection}[2][true]{ %
	% create environment that does nothing
	\provideenvironment*{#2}{}{}
	% check how to handle the contents
	\ifthenelse{\boolean{#1}}{
		% do nothing 		
	}{
		% hide contents of environment
		\excludecomment{#2}
	}
}%


\DefineTemplateSection[false]{TemplateMath}
\DefineTemplateSection[true]{TemplateFigures}

% \newenvironment{TemplateMath}{}{}
% \newenvironment{TemplateFigures}{}{}

\begin{TemplateMath}
\usepackage{amsmath}
\end{TemplateMath}
%
\begin{TemplateFigures}
\usepackage{graphicx}
\end{TemplateFigures}

\listfiles

\begin{document}
\end{document}


Verfasst: Mo 1. Nov 2010, 20:20
von KOMA
Dein Hauptproblem ist, dass eine normale Umgebung - und dazu gehört auch eine mit \provideenvironment (Deine Version davon funktioniert übrigens nicht wie \newenvironment o. ä.) definierte - immer eine Gruppe einfügt. Ein Paket in einer Gruppe zu laden ist aber .. naja, ich muss das sicher nicht weiter ausführen.

comment bietet aber bereits alles, was Du brauchst.
\newcommand{\DefineTemplateSection}[2][true]{%
  % check how to handle the contents
  \ifthenelse{\boolean{#1}}{%
    \includecomment{#2}%
  }{%
    % hide contents of environment
    \excludecomment{#2}%
  }%
}%
Ansonsten würde natürlich für Deinen Zweck auch etwas wie \newif genügen:
\newif\ifVariantSectionMathe\ifVariantSectionMathefalse
...
\ifVariantSectionMathe
\usepackage{amsmath}
\fi

Verfasst: Mo 1. Nov 2010, 20:56
von pospiech
D.h. wenn ich das über einen normalen Befehl mache würde es funktionieren, aber bei einer Umgebung(Gruppe) nicht?

Das ist insofern schade, weil man das Ende der Umgebung, als der schließenden Klammer des Befehls leicht übersieht.

Dein \DefineTemplateSection würde wenn ich das richtig verstehe so funktionieren:
\DefineTemplateSection{true}
{
    \usepackage{...}
}
Ich müsste das dann so umbasteln das es eher so lauten würde
\IfUseInTemplate[true]{math}
{
    \usepackage{...}
}

Verfasst: Mo 1. Nov 2010, 21:21
von KOMA
Mein \DefineTemplateSection mit \includecomment funktioniert genau so, wie Du Dir das AFAIK für Deine Version gewünscht hast, weil nämlich mit comment definierte Umgebungen keine normalen Umgebungen sind und insbesondere keine Gruppe darstellen. Du musst also nichts weiter tun, als Deine \DefineTemplateSection-Definition durch meine zu ersten, damit Dein Beispiel funktioniert. Die Definition von \provideenvironment kannst Du dann natürlich auch gleich rauswerfen, weil Du die dann nicht mehr brauchst.

Verfasst: Mo 1. Nov 2010, 22:22
von pospiech
Stimmt, es funktioniert soweit.

Aber: es gibt Pakete die doch von anderen Paketen geladen werden.
Um gezielt einzelen Pakete am Laden zu hindern (vor allem zum debuggen) wäre es hilfreich wenn man das einzeln einschränken könnte.

Das was ich mir vorstelle wäre dann sowas:
% disable loading of package
\DisablePackage{hyperref}
% oder
\DisablePackages{hyperref,microtype}

\usepackage{hyperref,microtype} % wird beides nicht geladen
kann man \usepackage 'gefahrlos' umdefinieren?

Was ich mir vorstelle ist sowas wie das hier - was anscheint sogar funktioniert, nur das ich nicht weiß wie man auf existenz von boolean tested
\documentclass[]{article}

\RequirePackage{ifthen}
\makeatletter
\providecommand\createboolean[2]{%
   \newboolean{#1}\setboolean{#1}{#2}
}%
\let\usepackage\template@usepackage
\providecommand{\usepackage}[2][]{%
  \ifthenelse{\boolean{ifload@#2}}{
	  \template@usepackage[#1]{#2}
  }{
    % package not loaded
  }
}
\providecommand{\DisablePackage}[1]{%
  \createboolean{ifload@#1}{false}%
}%
\providecommand{\EnablePackage}[1]{%
  \createboolean{ifload@#1}{true}%
}%

\makeatother

%\DisablePackage{graphicx}
\usepackage{graphicx}


\listfiles

\begin{document}
\end{document}



Verfasst: Di 2. Nov 2010, 11:12
von KOMA
Zunächst darfst Du in dem Fall nicht \usepackage umdefinieren, sondern solltest \RequirePackage angehen. Innerhalb von Paketen wird nämlich damit gearbeitet. Dann hast Du natürlich das Problem, dass Dir Optionen ggf. als unbenutzt gemeldet werden, die nur von den deaktivierten Paketen ausgewertet werden. Hierfür gibt es keine wirklich gute Lösung, sondern Du musst entscheiden, ob Du generell keine solche Warnungen willst, oder aber diese Warnungen einfach unbeachtet lassen willst.

Ich würde persönlich zur zweiten Lösung tendieren. In dem Fall würde ich einen etwas anderen Ansatz verwenden, als Du, nämlich eher etwas wie in Richtung \ignorepackages{Paket1,Paket2,Paket3,...}. Um eine solche Lösung zu testen, brauche ich allerdings noch etwas Zeit (ich suche gerade danach, ab welcher Kernel-Version das acpi-Modul bei mir einen hard-lock verursacht und habe deshalb immer nur kleine Portionen an Zeit zwischendurch).

Verfasst: Di 2. Nov 2010, 12:09
von KOMA
\documentclass{article}

\makeatletter
\newcommand*{\@excludepackages}{}
\let\@excludepackages\@empty% eigentlich nicht notwendig, aber wer weiß, was
                            % \newcommand noch alles anstellt.
\newcommand*{\excludepackages}[1]{%
  \edef\@excludepackages{\@excludepackages,\zap@space#1 \@empty}%
}
\newcommand*{\OriginalRequirePackage}{}
\let\OriginalRequirePackage\RequirePackage
\renewcommand*{\RequirePackage}[2][]{%
  \typeout{TRACE: Mein \string\RequirePackage}%
  \ifx\@excludepackages\@empty% Keine Ausnahmen
    \typeout{TRACE: Keine Ausnahmen}%
    \edef\reserved@c{,#2}%
  \else
    % Alle Pakete durchgehen (wir erinnern und, dass das Argument von
    % \RequirePackage eine Liste sein kann):
    \let\reserved@c\@empty% Neue Ladeliste
    \@for\reserved@b:=#2\do {%
      \begingroup
        \@tempswatrue % Paket laden
        \@for\reserved@a:=\@excludepackages\do {% Liste der ausgenommenen Pakete
                                                % durchgehen 
          \ifx\reserved@a\reserved@b % Das aktuelle Paket ist in der Liste
            \@tempswafalse % Paket nicht laden
          \fi
        }%
        \if@tempswa
          \xdef\reserved@c{\reserved@c,\reserved@b}%Paket in die neue Liste
        \fi
      \endgroup
    }%
  \fi
  % Übrige Pakete laden, dabei das Komma am Anfang der Liste entfernen.
  \edef\reserved@a{\noexpand\OriginalRequirePackage[#1]{%
      \expandafter\@gobble\reserved@c\@empty}}%
  \reserved@a
}
\ifx\usepackage\OriginalRequirePackage
  \let\usepackage\RequirePackage% Das macht LaTeX selbst auch,
                      % muss aber wiederholt werden, weil sonst das
                      % alte \RequirePackage (also \OriginalRequirePackage)
                      % für \usepackage verwendet wird.
\else
  % Hier fehlt noch eine Fehlerbehandlung bezüglich eines unerwartet
  % (durch irgend ein anderes Paket) umdefinierten \usepackage
\fi
\makeatother

\excludepackages{scrlfile}
% Die folgende Zeile ergibt einen Fehler, weil typearea auf scrlfile
% angewiesen ist, wir das Laden dieses Pakets aber verboten haben.
\usepackage{scrbase,scrlfile,typearea}

\begin{document}

\end{document}

Verfasst: Di 2. Nov 2010, 16:57
von pospiech
Erstmal vielen Dank für diesen sehr gut dokumentierten Code!
KOMA hat geschrieben: Ich würde persönlich zur zweiten Lösung tendieren. In dem Fall würde ich einen etwas anderen Ansatz verwenden, als Du, nämlich eher etwas wie in Richtung \ignorepackages{Paket1,Paket2,Paket3,...}.
Mir ist nicht ganz klar ob deine letzte Lösung deiner Idee von \ignorepackages entspricht, oder ob du damit noch etwas anderes im Sinn hattest.

Verfasst: Di 2. Nov 2010, 17:26
von KOMA
pospiech hat geschrieben:Mir ist nicht ganz klar ob deine letzte Lösung deiner Idee von \ignorepackages entspricht
Genau. Ich habe nur das Makro stattdessen \excludepackages genannte.

Verfasst: Do 2. Dez 2010, 22:31
von pospiech
Ich wollte die Variante mit \newif \if usw mal ausprobieren und habe folgendes versucht:
\documentclass{article}

\providecommand{\DefineTemplateSectionX}[2][true]{%
  \newif\ifTemplateSection#2
  \TemplateSection#2#1
  % \createboolean{bool@templatesection@#2}{#1}%
}%
\providecommand{\SetTemplateSectionX}[2]{%
  \TemplateSection#2#1
  %\setboolean{bool@templatesection@#2}{#1}%
}%
\providecommand{\BeginTemplateSection}[1]{%
	\ifTemplateSection#1
}
\providecommand{\EndTemplateSection}[1]{%
	\fi
}

\DefineTemplateSectionX[true]{PackagesBase}

\begin{document}
Hello
\BeginTemplateSection{PackagesBase}
World
\EndTemplateSection{PackagesBase}
\end{document}
Wenn ich im Dokument nun versuche ein \if zu definieren, dann bekomme ich aber eine Fehlermeldung
l.19 \DefineTemplateSectionX[true]{PackagesBase}
You're in trouble here. Try typing <return> to proceed.
If that doesn't work, type X <return> to quit.
! Undefined control sequence.
\\DefineTemplateSectionX ...n #2 \TemplateSection
#2#1
l.19 \DefineTemplateSectionX[true]{PackagesBase}
The control sequence at the end of the top line
of your error message was never \def'ed.
was mache ich falsch?