결과

결과

패키지에 대해 다음 코드를 고려하십시오.

% 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

다음 동작으로 다음 세 가지 함수를 정의하고 싶습니다.

  • \setcolors: 문서의 나머지 부분에 대한 변경 firstcolorsecondcolor호출 시점
  • \resetcolors: setcolors에 의한 모든 변경 사항을 잊어버리고 패키지의 원래 옵션으로 되돌립니다.
  • \printcolors: 기본적으로 현재 전역 firstcolor및 를 사용 secondcolor하지만 전역 값을 로컬 값으로 재정의하는 선택적 매개변수가 있습니다.
  • \newcolortheme: 두 쌍에 특별한 이름을 부여하기 위해 색상 테마를 생성할 수 있는 가능성을 제공합니다 firstcolor.secondcolor

사용자 측에서는 다음과 같이 보입니다.

\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}

나는 그것을 어떻게 할 수 있는지 전혀 모른다.

질문 :\setcolors, \resetcolors, 를 어떻게 정의 \printcolors하고 \newcolortheme그렇게 만들까요?

답변1

가능한 방법은 다음과 같습니다.

\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}

(참고: \setcolor매크로는 의 별칭과 같습니다 \mypackage@set.)

결과

여기에 이미지 설명을 입력하세요

답변2

다음은 \printcolors그룹화 없이 이를 달성하는 두 가지 방법을 보여줍니다(바람직할 수도 있고 그렇지 않을 수도 있음).

이 두 코드는 모두 제품군의 패키지를 사용합니다 expkv(부인 성명:그 중 제가 저자입니다). 첫 번째는 expkv-cs핵심에서 사용하므로 그룹이 필요하지 않은 코드 작성이 매우 간단해집니다(key=value 처리기는 할당이 필요하지 않으므로 매크로는 \printcolors할당 없이 확장만으로 작동합니다. 제외하는 경우). 이 주장의 선택적 인수에 대한 구문 분석). 두 번째는 단순히 각 호출에서 기본값을 재설정하고(성능이 좋은 방식으로) \setcolors기본값으로 다시 설정하는 데 사용되는 매크로를 변경합니다.

\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}

\usepackage{\jobname}귀하 또는 결과 에 관계없이 \usepackage{\jobname2}다음과 같습니다.

여기에 이미지 설명을 입력하세요

관련 정보