2

I want to use key-svalue options for my package and I tried a solution with pgfopts. It must be possible 1) to load the package with e.g.

\usepackage[colors=1]{mypack}

2) to change the color somewhere in the usercode, not only in the preamble, with something like

\MPset{colors=2}

and 3) to test which color is active.

In my real world package there are 2 more options concerning language and messages, so maybe pgfopts is an overkill. I would gladly accept any working solution with any key-val package.

\ProvidesPackage{mypack}
\RequirePackage{%
xcolor,
pgfopts
}

\def\MPset#1{\pgfqkeys{/MP}{ /#1}}
\MPset{colors/.initial=2}
\MPset{colors/.is choice}
\MPset{colors/1/.code={\def\test{\textcolor{black}{TEST}}}}
\MPset{colors/2/.code={\def\test{\textcolor{red}{TEST}}}}
\MPset{colors/3/.code={\def\test{\textcolor{blue}{TEST}}}}

\ProcessPgfPackageOptions{/MP}
\endinput% mypack.sty

I use mypack in this test document

\documentclass{article}
%\usepackage[colors=1]{mypack}
\usepackage{mypack}
\MPset{colors=2}
\begin{document}
  :\pgfkeysvalueof{colors}:
  \test
\end{document}
\endinput

If I load mypack with

\usepackage[colors=1]{mypack}

I get this error

! Package pgfkeys Error: I do not know the key '/MP/colors', to which you
  passed '1', and I am going to ignore it. Perhaps you misspelled it.

See the pgfkeys package documentation for explanation.
Type  H <return>  for immediate help.
 ...

l.16 \ProcessPgfPackageOptions{/MP}

If I load mypack without an option it does compile, but

\pgfkeysvalueof{colors}

is empty. When I uncomment

\test

I get the wanted colored text, but I still cannot test which color is active

  • Your \MPset macro should be defined by def\MPset#1{\pgfqkeys{/MP}{#1}} – Paul Gaborit Feb 9 '18 at 12:16
  • Your test should be \pgfkeysvalueof{/MP/colors}. – Paul Gaborit Feb 9 '18 at 12:17
  • @Paul I thought I tried all possible combinations. Must have overlooked some! With eihter option or through MPset, I get the right color now. But the test always yields 2, the initial value. Any idea? – Jack Feb 9 '18 at 13:09
1

Here is a corrected version of your code:

\documentclass{article}
%------------------------------
\usepackage{filecontents}
\begin{filecontents*}{mypack.sty}
\ProvidesPackage{mypack}
\RequirePackage{%
xcolor,
pgfopts
}

\pgfkeys{/MP/.is family}
\def\MPset#1{\pgfkeys{/MP,#1}}
\MPset{
  colors/.is choice,
  colors/1/.code={\def\test{\textcolor{black}{TEST}}},
  colors/2/.code={\def\test{\textcolor{red}{TEST}}},
  colors/3/.code={\def\test{\textcolor{blue}{TEST}}},
  % default value
  colors=2,
}

\ProcessPgfPackageOptions{/MP}
\endinput% mypack.sty
\end{filecontents*}
%------------------------------

\usepackage[colors=3]{mypack}
%\MPset{colors=2}
\begin{document}
  \test
\end{document}

Here is a modified version to (try to) match your requirements.

  • The \MPspecial macro uses the MP@uses@italic TeX-if to choose between italic or color.
  • The use italic key sets the MP@uses@italic TeX-if to true or false.
  • The define current color key defines the current color (via xcolor) and incidentally store its current name in \MP@current@color.
  • The colors key is a choice with three alternatives (black, blue, red) and defines the MP current color. The red and blue colors set use italic to false and the black color sets use italic to true.
\documentclass{article}
%------------------------------
\usepackage{filecontents}
\begin{filecontents*}{mypack.sty}
\ProvidesPackage{mypack}
\RequirePackage{xcolor}
\RequirePackage{pgfopts}

\newif\ifMP@uses@italic
\pgfkeys{/MP/.is family}
\def\MPset#1{\pgfkeys{/MP,#1}}
\MPset{
  % some special macros use italic istead of black
  use italic/.is if=MP@uses@italic,
  use italic=false, % default value
  % define the current color
  define current color/.code={\def\MPcurrent@color@name{#1}\colorlet{current MP color}{#1}},
  % 
  colors/.is choice,
  colors/black/.style={use italic=true,define current color=black},
  colors/red/.style={use italic=false,define current color=red},
  colors/blue/.style={use italic=false,define current color=blue},
  % default value
  colors=red,
}

\def\MPspecial#1{\ifMP@uses@italic\textit{#1}\else\textcolor{current MP color}{#1}\fi}
\def\test{\textcolor{current MP color}{TEST (in \MPcurrent@color@name)}}

\ProcessPgfPackageOptions{/MP}
\endinput% mypack.sty
\end{filecontents*}
%------------------------------
\pagestyle{empty}
\usepackage[colors=red]{mypack}
\begin{document}
\test{} \MPspecial{My text}

\MPset{colors=black}
\test{} \MPspecial{My text}

\MPset{colors=blue}
\test{} \MPspecial{My text}

\end{document}

enter image description here

  • Thank you Paul. Unfortunately, the test \pgfkeysvalueof{/MP/colors} still yields the empty string. – Jack Feb 9 '18 at 17:09
  • @Jack It's normal. The .is choice handler defines the /MP/colors key as a command (like a macro), not as a value. – Paul Gaborit Feb 9 '18 at 18:56
  • Dear Paul, thanks again for your answer. As a complete novice with regard to pgfopts, I have a couple of questions: 1) My requirement nr 3 stated that it must be possible to test which color is active. Of course I can do that by storing this information in the code for the colors. Is it impossible retrieve this directly from pgfopts? 2) Why did you introduce "family"? 3) Is the "choice" related to the fact that it is an option of the package or just that the user can select a value at any time? 4) Do you think pgfopts is the right approach for this simple application? Regards Jack – Jack Feb 9 '18 at 21:13
  • 1) Why do you want to "test which color is active"? It's probably an XY problem! What is your real need? 2) family is only a writing facility. 3) .is choice allows to define the authorized values. 4) Any key/value package could be suitable. pgfopts(in fact pgfkeys) is just the most powerful. – Paul Gaborit Feb 9 '18 at 22:42
  • 1) I set diagrams and to mark a special situation, some things are written in red. When the user specifies only 1 color (=black and white), I use italics to mark this situation. (Sorry, I don't know what an XY problem is). 2) So one can leave it out without changing something else? 4) I know that, but do I need this power for this tiny application? BTW does not answering my question 1, implies that pgfopts cannot do that directly? Regards – Jack Feb 9 '18 at 23:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.