使用 pgfopts 设置 tcolorbox 样式

使用 pgfopts 设置 tcolorbox 样式

考虑一个包文件eqbox.sty

% Preamble
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{eqbox}[2018/01/01 Boxed Equations]

% Packages
\RequirePackage{xcolor}
\RequirePackage{pgfopts}
\RequirePackage{amsmath}
\RequirePackage{fancybox}
\RequirePackage[most]{tcolorbox}

% Options
\pgfkeys{
    /eqbox/.cd,
    colframe/.store in = \colframe,
    colframe/.default = {black},
    colback/.store in = \colback,
    colback/.default = {white},
    shadow/.store in = \shadow,
    shadow/.default = {black},
}
\ProcessPgfPackageOptions*

% Body
\tcbset{
    highlight math style={
        enhanced,
        sharp corners,
        breakable,
        colframe=\colframe{},
        colback=\colback{},
        boxrule=0.4pt,
        shadow={2pt}{-2pt}{0mm}{\shadow{}},
        boxsep = 3pt,
        left = 0pt,
        right = 0pt,
        top = 0pt,
        bottom = 0pt
    }
}

以及.tex使用该包的文件:

% Preamble
\documentclass[letterpaper, 11pt, onecolumn]{article}

% Packages
\usepackage{lipsum}
\usepackage{eqbox}

% Body
\begin{document}
\lipsum
\begin{equation}
\tcbhighmath{x^2 + 3}
\end{equation}
\lipsum
\end{document}

我是初学者pgf,我尝试的方法似乎不起作用。我想在包中有三个选项:colbackcolframeshadow。例如使用以下语法:

\usepackage{eqbox}

或者

\usepackage[shadow=blue]{eqbox}

或者

\usepackage[%
    colback=red,
    shadow=\color[RGB]{100,150,200},
]{eqbox}

为了举例,我想:

  • colframe默认blue
  • colback默认undefined
  • shadow默认为undefined(如果shadowundefined,则不希望此行shadow={2pt}{-2pt}{0mm}{\shadow{}}出现在tcbset

我也不想“污染”全局命名空间,所以从包用户的角度来看,我不希望该命令\shadow在主tex文件中被人知道(我希望它是包的内部细节eqbox)。

如何以最干净的方式做到这一点?

答案1

当你拨打电话时会发生什么情况\pgfkeys{key1, key2=value2, ...}取决于pgf 手册

请注意,该\pgfkeys命令是pgfkeys包,而\ProcessPgfPackageOptions来自pgfopts。此命令有效地调用传递给包选项的\pgfkeys{/package/key=value}每一对。在您的例子中,key=value

\usepackage[shadow=blue]{eqbox}

将会在内部进行处理,eqbox.sty就像通过调用一样\pgfkeys{/eqbox/shadow=blue}

注意

\pgfkeys{/path/key=...}

是相同的

\pgfkeys{
  /path/.cd,
  key=...
}

虽然等号让它看起来像是,但\pgfkeys{key=value}实际上并不是赋值。要使其表现得像赋值,您需要先调用

\pgfkeys{key/.store in=\someMacroName}

之后,调用\pgfkeys{key=value}将把宏定义\someMacroNamevalue

您可能还会对以下内容感到困惑:

\pgfkeys{key/.default=value}

它不会为 分配默认值key;相反,它会导致所有后续调用都\pgfkeys{key}表现为\pgfkeys{key=value}

综合起来,您的示例变成:

% eqbox.sty

\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{eqbox}[2018/01/01 Boxed Equations]

\RequirePackage{pgfopts}
\RequirePackage[most]{tcolorbox}

\pgfkeys{
  /eqbox/.cd,  % Change the prefix path to /eqbox/
  %
  colframe/.store in=\colframe, % Make subsequent calls to 
                                % \pgfkeys{/eqbox/colframe=<value>}
                                % cause \def\colframe{<value>}
  %
  colframe=black,   % Hence, this causes \def\colframe{black},
                    % which is effectively a default value.
  %
  % Same for the rest of the keys.
  colback/.store in=\colback,
  colback=white,
  shadow/.store in=\shadow,
  shadow=black
}

\ProcessPgfPackageOptions{/eqbox} % If the .tex file contains
                                  % \usepackage[shadow=purple]{eqbox},
                                  % that would result in the call
                                  % \pgfkeys{/eqbox/shadow=purple}.
                                  % This will in turn cause \def\shadow{purple},
                                  % because of the .store handler.

\tcbset{
  highlight math style={
    enhanced,
    sharp corners,
    breakable,
    colframe=\colframe,
    colback=\colback,
    boxrule=0.4pt,
    shadow={2pt}{-2pt}{0mm}{\shadow},
    boxsep=3pt,
    left=0pt,
    right=0pt,
    top=0pt,
    bottom=0pt
  }
}
% .tex file that uses the package

\documentclass[letterpaper, 11pt, onecolumn]{article}

\usepackage[shadow=purple]{eqbox}

\begin{document}
\begin{equation}
\tcbhighmath{x^2 + 3}
\end{equation}
\end{document}

结果:

在此处输入图片描述

如果你想检测包用户是否为某个选项提供了值,请说myoption

% In mypackage.sty

\def\someDefaultValue{myDefaultValue}

\pgfkeys{
  /mypackage/myoption/.store in=\myoption,
  /mypackage/myoption=\someDefaultValue
}

\ProcessPgfPackageOptions{/mypackage}

\ifx\someDefaultValue\myoption
  % User did not supply myoption=value
\else
  % User supplied some value,
  % now stored in \myoption
\fi

对于最后一部分,另请参阅https://tex.stackexchange.com/a/53091/80468

相关内容