TeX - LaTeX Asked by J.-E. Pin on January 13, 2021
I would like to create a command to pass easily from color to black-and-white pictures. For this purpose, I would like to use a newif ifBlackAndWhite
together with a macro myCommand
such that if ifBlackAndWhitetrue
, then
begin{pspicture}(0,0)(2,2)
pscircle[myCommand, linewidth=1mm](1,1){0.5}
end{pspicture}
becomes
begin{pspicture}(0,0)(2,2)
pscircle[fillstyle=none, linewidth=1mm](1,1){0.5}
end{pspicture}
and if ifBlackAndWhitefalse
, then it becomes
begin{pspicture}(0,0)(2,2)
pscircle[fillstyle=solid, fillcolor=red, linewidth=1mm](1,1){0.5}
end{pspicture}
Is it possible to define such a macro? A naive template below…
documentclass{article}
usepackage{pstricks}
newcommand{myCommand}{...}
newififBlackAndWhite BlackAndWhitefalse
ifBlackAndWhite
renewcommand{myCommand}{...}
fi
begin{document}
begin{pspicture}(0,0)(2,2)
pscircle[fillstyle=none, linewidth=1mm](1,1){0.5}
end{pspicture}
begin{pspicture}(0,0)(2,2)
pscircle[fillstyle=solid, fillcolor=red, linewidth=1mm](1,1){0.5}
end{pspicture}
begin{pspicture}(0,0)(2,2)
pscircle[myCommand, linewidth=1mm](1,1){0.5}
end{pspicture}
end{document}
You need to change the expansion order. For simple commands like pscircle
you can define variants that do that for you (ePScircle
below). For more complicated commands this is not so easy. Which is why you may want to considering switching to TikZ, where styles can do all of this with ease.
documentclass{article}
usepackage{pstricks}
newififBlackAndWhite
BlackAndWhitefalse
newcommandmyCommand{ifBlackAndWhite
fillstyle=none%
else
fillstyle=solid,fillcolor=red%
fi}
defePScircle[#1](#2)#3{expanded{noexpandpscircle[#1](#2){#3}}}
begin{document}
begin{pspicture}(0,0)(2,2)
pscircle[fillstyle=none, linewidth=1mm](1,1){0.5}
end{pspicture}
begin{pspicture}(0,0)(2,2)
pscircle[fillstyle=solid, fillcolor=red, linewidth=1mm](1,1){0.5}
end{pspicture}
BlackAndWhitetrue
begin{pspicture}(0,0)(2,2)
expanded{noexpandpscircle[myCommand, linewidth=1mm](1,1){0.5}}
end{pspicture}
BlackAndWhitefalse
begin{pspicture}(0,0)(2,2)
expanded{noexpandpscircle[myCommand, linewidth=1mm](1,1){0.5}}
end{pspicture}
BlackAndWhitetrue
begin{pspicture}(0,0)(2,2)
ePScircle[myCommand, linewidth=1mm](1,1){0.5}
end{pspicture}
BlackAndWhitefalse
begin{pspicture}(0,0)(2,2)
ePScircle[myCommand, linewidth=1mm](1,1){0.5}
end{pspicture}
end{document}
Correct answer by user232027 on January 13, 2021
The optional parameters passed to any PStricks object is not expanded. You can redefine the macro that captures the optional parameters - pst@@object
- to use an edef
instead of a regular def
:
makeatletter
defpst@@object#1[#2]{%
edefpst@par{#2}% Changed from def to edef
@ifnextchar+{@nameuse{#1@i}}{@nameuse{#1@i}}%
}
makeatother
A little more elegant is probably to use an etoolbox
patch:
usepackage{etoolbox}
makeatletter
% patchcmd{<cmd>}{<search>}{<replace>}{<success>}{<failure>}
patchcmd{pst@@object}% <cmd>
{def}% <search>
{edef}% <replace>
{}{}% <success><failure>
makeatother
An edef
will expand the parameters once, which is probably sufficient in most cases.
documentclass{article}
usepackage{pstricks}
usepackage{etoolbox}
makeatletter
% patchcmd{<cmd>}{<search>}{<replace>}{<success>}{<failure>}
patchcmd{pst@@object}% <cmd>
{def}% <search>
{edef}% <replace>
{}{}% <success><failure>
makeatother
newcommand{myCommand}{fillstyle=solid, fillcolor=red}
newififBlackAndWhite BlackAndWhitefalse
ifBlackAndWhite
renewcommand{myCommand}{fillstyle=none}
fi
begin{document}
begin{pspicture}(0,0)(2,2)
pscircle[fillstyle=none, linewidth=1mm](1,1){0.5}
end{pspicture}
begin{pspicture}(0,0)(2,2)
pscircle[fillstyle=solid, fillcolor=red, linewidth=1mm](1,1){0.5}
end{pspicture}
begin{pspicture}(0,0)(2,2)
pscircle[myCommand, linewidth=1mm](1,1){0.5}
end{pspicture}
end{document}
And here is the output with BlackAndWhitetrue
:
Answered by Werner on January 13, 2021
Here is a variant of the solution of user232027 which does with protected@edef@tempa{...}
instead of expanded{...}
.
I present it only because older TeX-engines don't have expanded
.
Nonetheless I definitely prefer the solution of user232027 because a disadvantage of my variant is that you need to double hashes within the optional argument.
(I don't know if the optional argument of pscircle
can contasin hashes.)
Unlike the solution of user232027 where all arguments are expanded my variant does only expand the optional argument if present.
documentclass{article}
usepackage{pstricks}
newififBlackAndWhite
BlackAndWhitefalse
makeatletter
newcommandmyCommand{%
ifBlackAndWhiteexpandafter@firstoftwoelseexpandafter@secondoftwofi
{fillstyle=none}{fillstyle=solid,fillcolor=red}%
}
newcommandePScircle{@ifnextchar[{ePScircleOpt}{pscircle}}%
newcommandePScircleOpt[1][]{%
{protected@edef@tempa{#1}expandafter}%
expandafterpscircleexpandafter[expandafter{@tempa}]%
}%
makeatother
begin{document}
begin{pspicture}(0,0)(2,2)
pscircle[fillstyle=none, linewidth=1mm](1,1){0.5}
end{pspicture}
begin{pspicture}(0,0)(2,2)
pscircle[fillstyle=solid, fillcolor=red, linewidth=1mm](1,1){0.5}
end{pspicture}
BlackAndWhitetrue
begin{pspicture}(0,0)(2,2)
expanded{noexpandpscircle[myCommand, linewidth=1mm](1,1){0.5}}
end{pspicture}
BlackAndWhitefalse
begin{pspicture}(0,0)(2,2)
expanded{noexpandpscircle[myCommand, linewidth=1mm](1,1){0.5}}
end{pspicture}
BlackAndWhitetrue
begin{pspicture}(0,0)(2,2)
ePScircle[myCommand, linewidth=1mm](1,1){0.5}
end{pspicture}
BlackAndWhitefalse
begin{pspicture}(0,0)(2,2)
ePScircle[myCommand, linewidth=1mm](1,1){0.5}
end{pspicture}
end{document}
Similar to egreg's approach you can define a key which evaluates the ifBlackAndWhite
-switch:
documentclass{article}
usepackage{pstricks}
makeatletter
newififBlackAndWhite
BlackAndWhitefalse
define@key[psset]{pstricks}{myfill}[]{%
ifBlackAndWhiteexpandafter@firstoftwoelseexpandafter@secondoftwofi
{setkeys+[psset]{pstricks}{fillstyle=none}}%
{setkeys+[psset]{pstricks}{fillstyle=solid,fillcolor=red}}%
}%
makeatother
begin{document}
BlackAndWhitefalse
begin{pspicture}(0,0)(2,2)
pscircle[myfill, linewidth=1mm](1,1){0.5}
end{pspicture}
BlackAndWhitetrue
begin{pspicture}(0,0)(2,2)
pscircle[myfill, linewidth=1mm](1,1){0.5}
end{pspicture}
end{document}
Answered by Ulrich Diez on January 13, 2021
You could define your own key.
documentclass{article}
usepackage{pstricks}
makeatletter % switch the commented lines for changing the meaning of the key
define@key[psset]{pstricks}{myfill}[]{setkeys+[psset]{pstricks}{fillstyle=none}}
%define@key[psset]{pstricks}{myfill}[]{setkeys+[psset]{pstricks}{fillstyle=solid,fillcolor=red}}
makeatother
begin{document}
begin{pspicture}(0,0)(2,2)
pscircle[fillstyle=none, linewidth=1mm](1,1){0.5}
end{pspicture}
begin{pspicture}(0,0)(2,2)
pscircle[fillstyle=solid, fillcolor=red, linewidth=1mm](1,1){0.5}
end{pspicture}
begin{pspicture}(0,0)(2,2)
pscircle[myfill, linewidth=1mm](1,1){0.5}
end{pspicture}
end{document}
After switching the comments:
Answered by egreg on January 13, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP