Ergebnis

Ergebnis

Betrachten Sie den folgenden Code für ein Paket:

% Preamble
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{mypackage}[2024/01/01 MyPackage]
\makeatletter

% Dependencies
\RequirePackage{pgfopts}
\RequirePackage{xparse}
\RequirePackage{xcolor}

% Package options
\pgfkeys{
    /mypackage/.cd,
    firstcolor/.store in = \mypackage@firstcolor,
    firstcolor = blue,
    secondcolor/.store in = \mypackage@secondcolor,
    secondcolor = red,
}
\ProcessPgfPackageOptions{/mypackage}

% Definition of `\setcolors` here

% Definition of `\resetcolors` here

% Definition of `\printcolors` here

% Definition of `\newcolortheme` here

% End
\makeatother

Ich möchte die folgenden drei Funktionen mit folgendem Verhalten definieren:

  • \setcolors: ändern firstcolorund secondcoloram Aufrufpunkt für den Rest des Dokuments
  • \resetcolors: Alle von setcolors vorgenommenen Änderungen werden auf die ursprünglichen Optionen des Pakets zurückgesetzt.
  • \printcolors: verwendet standardmäßig die aktuellen globalen firstcolorund secondcolor, hat aber einen optionalen Parameter, um die globalen Werte durch lokale Werte zu überschreiben
  • \newcolortheme: bieten die Möglichkeit, ein Farbthema zu erstellen, um einem Paar von firstcolorund einen speziellen Namen zu gebensecondcolor

Auf der Benutzerseite würde das folgendermaßen aussehen:

\documentclass[12pt]{article}
\usepackage[firstcolor = green, secondcolor = yellow]{mypackage}
\newcolortheme{mytheme}{firstcolor = brown, secondcolor = cyan}

\begin{document}
\printcolors                      % Will print green and yellow
\printcolors[secondcolor = blue]  % Will print green and blue
\printcolors                      % Will print green and yellow

\setcolors{secondcolor = black}
\printcolors                      % Will print green and black
\printcolors[firstcolor = purple] % Will print purple and black
\printcolors                      % Will print green and black

\setcolors{firstcolor = red}
\printcolors                      % Will print red and black

\setcolors{firstcolor = orange, secondcolor = pink}
\printcolors                      % Will print orange and pink

\resetcolors
\printcolors                      % Will print green and yellow
\printcolors[mytheme]             % Will print brown and cyan
\printcolors                      % Will print green and yellow

\setcolors{mytheme}
\printcolors                      % Will print brown and cyan      
\end{document}

Ich habe keine Ahnung, wie ich das hinbekommen soll.

FRAGE :Wie definiert man \setcolors, \resetcolors, \printcolorsund \newcolorthemewie setzt man dies um?

Antwort1

Hier ist eine mögliche Methode:

\begin{filecontents*}[overwrite]{mypackage.sty}
% Preamble
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{mypackage}[2024/01/01 MyPackage]

% Dependencies
\RequirePackage{pgfopts}
\RequirePackage{xparse}
\RequirePackage{xcolor}

\pgfkeys{/mypackage/.is family}
\def\mypackage@set#1{\pgfkeys{/mypackage,#1}}

\mypackage@set{
  % storage
  first-color/.store in=\mypackage@firstcolor,
  second-color/.store in=\mypackage@secondcolor,
  % default value
  first-color=blue,
  second-color=red,
  mypackage@init/.style/.expanded={
    first-color=\mypackage@firstcolor,
    second-color=\mypackage@secondcolor
  }
}

\ProcessPgfPackageOptions{/mypackage}

\mypackage@set{
  mypackage@init/.style/.expanded={
    first-color=\mypackage@firstcolor,
    second-color=\mypackage@secondcolor
  }
}

\NewDocumentCommand\newcolortheme{mm}{\mypackage@set{#1/.style={#2}}}

\NewDocumentCommand\printcolors{O{}}{%
  \bgroup%
  \mypackage@set{#1}%
  \mypackage@firstcolor{} and \mypackage@secondcolor{}\par%
  \egroup
}

\NewDocumentCommand\setcolors{m}{\mypackage@set{#1}}

\NewDocumentCommand\resetcolors{}{\mypackage@set{mypackage@init}}
\end{filecontents*}


\documentclass[preview=true,varwidth=true]{standalone}

\usepackage[first-color=green, second-color=yellow]{mypackage}

\newcolortheme{my theme}{first-color=brown, second-color=cyan}
% \setcolors{my theme/.style={first-color=brown, second-color=cyan}}

\begin{document}
\printcolors                      % Will print green and yellow
\printcolors[second-color=blue]   % Will print green and blue
\printcolors                      % Will print green and yellow

\setcolors{second-color=black}
\printcolors                      % Will print green and black
\printcolors[first-color=purple]  % Will print purple and black
\printcolors                      % Will print green and black

\setcolors{first-color=red}
\printcolors                      % Will print red and black

\setcolors{first-color=orange, second-color=pink}
\printcolors                      % Will print orange and pink

\resetcolors
\printcolors                      % Will print green and yellow
\printcolors[my theme]            % Will print brown and cyan
\printcolors                      % Will print green and yellow

\setcolors{my theme}
\printcolors                      % Will print brown and cyan      
\end{document}

(Hinweis: Das \setcolorMakro ist wie ein Alias ​​von \mypackage@set)

Ergebnis

Bildbeschreibung hier eingeben

Antwort2

Im Folgenden werden zwei Methoden gezeigt, mit denen dies erreicht werden kann, ohne dass \printcolorseine Gruppierung erforderlich ist (was möglicherweise vorzuziehen ist, aber nicht muss).

Beide Codes verwenden Pakete der expkvFamilie (Haftungsausschluss:dessen Autor ich bin). Die erste verwendet expkv-csin ihrem Kern, was das Schreiben von Code, der keine Gruppen benötigt, ziemlich einfach macht (da der Schlüssel=Wert-Handler keine Zuweisungen benötigt, \printcolorsfunktioniert das Makro rein durch Erweiterung und ohne Zuweisungen – wenn man die Analyse für ein optionales Argument von dieser Behauptung ausnimmt). Die zweite setzt bei jedem Aufruf einfach die Standardwerte zurück (auf eine ziemlich leistungsfähige Weise) und \setcolorsändert nur das Makro, das zum Zurücksetzen auf die Standardwerte verwendet wird.

\begin{filecontents}{\jobname.sty}
\ProvidesPackage{\@currname}[2024-01-24 adhoc test package]

\RequirePackage{expkv-cs,expkv-opt,expkv-def}

% define keys as used for the package (we don't need the keys defined here
% otherwise)
\ekvdefinekeys{\@currname}
  {
     store   firstcolor  = \my@firstcolor
    ,initial firstcolor =  blue
    ,store   secondcolor = \my@secondcolor
    ,initial secondcolor = red
  }
\ekvoProcessLocalOptions{\@currname}

% parsing for an optional argument
\newcommand\printcolors[1][]{\@printcolors{#1}}
% assign default values ('o: ' means expand value once)
\ekvcSplit\@printcolors
  {
     o: firstcolor  = \my@firstcolor
    ,o: secondcolor = \my@secondcolor
  }
  {#1 and #2\par}
% just change the default values of the underlying ekvc-macro
\protected\def\setcolors{\ekvcChange\@printcolors}
% store the current values (package defaults), using \edef for expansion
\protected\edef\resetcolors
  {%
    \setcolors
      {%
        % control the expansion to only do a single step (most likely
        % unnecessary but we never know with arbitrary user input)
         firstcolor  = {\unexpanded\expandafter{\my@firstcolor}}
        ,secondcolor = {\unexpanded\expandafter{\my@secondcolor}}
      }%
  }
% just define '#1' to be considered additional key=value input '#2' using
% ekvcSecondaryKeys.
\protected\def\newcolortheme#1#2%
  {\ekvcSecondaryKeys\@printcolors{nmeta #1 = {#2}}}
\end{filecontents}

\begin{filecontents}{\jobname2.sty}
\ProvidesPackage{\@currname}[2024-01-24 adhoc test package]

\RequirePackage{expkv-opt,expkv-def}

\ekvdefinekeys{my}
  {
     store   firstcolor  = \my@firstcolor
    ,initial firstcolor =  blue
    ,store   secondcolor = \my@secondcolor
    ,initial secondcolor = red
  }
\ekvsetdef\@setcolors@keys{my}
\ekvoProcessLocalOptions{my}

% common code used to save the current values of all keys that should be
% persistent.
% 'o: ' means expand the value once before passing it to the key's code.
\newcommand*\my@storecolours@keys
  {%
     o: firstcolor  = \my@firstcolor
    ,o: secondcolor = \my@secondcolor
  }

% \@resetcolors is used to store the package default values
% 'R: ' means expand the following macro once and use it as key=value input
\protected\ekvcompile\@resetcolors{my}{R: \my@storecolours@keys}
% \@setcolors is used to restore the currently valid colours on each call
\protected\def\resetcolors{\let\@setcolors\@resetcolors}
\resetcolors
\protected\def\setcolors#1%
  {%
    % bit of juggling to get the normal key=value parser, but also build a fast
    % list of finalised colours
    \begingroup
      \ekvset{my}{#1}%
      \ekvcompile\@setcolors{my}{R: \my@storecolours@keys}%
    % expansion trick to store the meaning of \@setcolors as valid inside this
    % group outside the group, without needing any global assignments
    \expanded{\endgroup
    \protected\edef\noexpand\@setcolors
      {\noexpand\unexpanded{\unexpanded\expandafter{\@setcolors}}}%
    }%
  }
% just treat the key '#1' as additional key=value input containing '#2' (rather
% straight forward)
\protected\def\newcolortheme#1#2{\ekvdefNoVal{my}{#1}{\ekvmorekv{#2}}}

\newcommand\printcolors[1][]
  {%
    % restore current default values
    \@setcolors
    % maybe set different values
    \@setcolors@keys{#1}%
    % use values
    \my@firstcolor\space and \my@secondcolor
    \par
  }
\end{filecontents}

\documentclass[12pt]{article}

\usepackage[firstcolor = green, secondcolor = yellow]{\jobname} % both work
% \usepackage[firstcolor = green, secondcolor = yellow]{\jobname2} % both work

\newcolortheme{mytheme}{firstcolor = brown, secondcolor = cyan}

\begin{document}
\printcolors                      % Will print green and yellow
\printcolors[secondcolor = blue]  % Will print green and blue
\printcolors                      % Will print green and yellow

\bigskip
\setcolors{secondcolor = black}
\printcolors                      % Will print green and black
\printcolors[firstcolor = purple] % Will print purple and black
\printcolors                      % Will print green and black

\bigskip
\setcolors{firstcolor = red}
\printcolors                      % Will print red and black

\bigskip
\setcolors{firstcolor = orange, secondcolor = pink}
\printcolors                      % Will print orange and pink

\bigskip
\resetcolors
\printcolors                      % Will print green and yellow
\printcolors[mytheme]             % Will print brown and cyan
\printcolors                      % Will print green and yellow

\bigskip
\setcolors{mytheme}
\printcolors                      % Will print brown and cyan      
\end{document}

Egal ob bei Ihnen \usepackage{\jobname}oder bei \usepackage{\jobname2}Ihnen, das Ergebnis wird so aussehen:

Bildbeschreibung hier eingeben

verwandte Informationen