Test if Current Color is Black












11














The MWE below does exactly what I want via the TypsetInBlueOnlyIfCurrentColorIsBlack macro:



enter image description here



TypsetInBlueOnlyIfCurrentColorIsBlack is intended to change the color of its parameter to blue, only if the current color is black. Otherwise, the current color is to be used.



Questions:




  • I expected that xcolor would provide a macro to do this, but was not able to locate it. Thus, wondering if there any obvious problems with this approach, or is there an official interface that is provided.


References:




  • This solution is adapted from How to get a textual representation of the current color?
    .


Code:



documentclass{article}
usepackage{xcolor}
usepackage{xstring}

%% At this point the default color is black so save that.
edefBlackColor{csnamestringcolor@.endcsname}

makeatletter
newcommand{@CurrentColor}{}% Make sure we are not using an existing macro
newcommand*{TypsetInBlueOnlyIfCurrentColorIsBlack}[1]{%
edef@CurrentColor{csnamestringcolor@.endcsname}% Get current color
IfStrEq{@CurrentColor}{BlackColor}{%
{bfseriesttfamilytextcolor{blue}{#1}}% current color IS black
}{%
{bfseriesttfamily#1}% current color is NOT black
}%
}
makeatother

begin{document}
Following should be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}.

color{red}
Following should be in red:
TypsetInBlueOnlyIfCurrentColorIsBlack{red}.

color{blue}
Following should also be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}.
end{document}









share|improve this question


















  • 2




    color stores the current colour in current@color. So you could do usepackage{xcolor}{color{black}globalletmy@black@colorcurrent@color}newcommand*ifblack{ifxmy@black@colorcurrent@color}.
    – Skillmon
    Dec 15 '18 at 22:20










  • @Skillmon Better yet: sbox0{color{black}globalletmy@black@colorcurrent@color} so no whatsit is added to the main vertical list.
    – egreg
    Dec 16 '18 at 0:00
















11














The MWE below does exactly what I want via the TypsetInBlueOnlyIfCurrentColorIsBlack macro:



enter image description here



TypsetInBlueOnlyIfCurrentColorIsBlack is intended to change the color of its parameter to blue, only if the current color is black. Otherwise, the current color is to be used.



Questions:




  • I expected that xcolor would provide a macro to do this, but was not able to locate it. Thus, wondering if there any obvious problems with this approach, or is there an official interface that is provided.


References:




  • This solution is adapted from How to get a textual representation of the current color?
    .


Code:



documentclass{article}
usepackage{xcolor}
usepackage{xstring}

%% At this point the default color is black so save that.
edefBlackColor{csnamestringcolor@.endcsname}

makeatletter
newcommand{@CurrentColor}{}% Make sure we are not using an existing macro
newcommand*{TypsetInBlueOnlyIfCurrentColorIsBlack}[1]{%
edef@CurrentColor{csnamestringcolor@.endcsname}% Get current color
IfStrEq{@CurrentColor}{BlackColor}{%
{bfseriesttfamilytextcolor{blue}{#1}}% current color IS black
}{%
{bfseriesttfamily#1}% current color is NOT black
}%
}
makeatother

begin{document}
Following should be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}.

color{red}
Following should be in red:
TypsetInBlueOnlyIfCurrentColorIsBlack{red}.

color{blue}
Following should also be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}.
end{document}









share|improve this question


















  • 2




    color stores the current colour in current@color. So you could do usepackage{xcolor}{color{black}globalletmy@black@colorcurrent@color}newcommand*ifblack{ifxmy@black@colorcurrent@color}.
    – Skillmon
    Dec 15 '18 at 22:20










  • @Skillmon Better yet: sbox0{color{black}globalletmy@black@colorcurrent@color} so no whatsit is added to the main vertical list.
    – egreg
    Dec 16 '18 at 0:00














11












11








11


2





The MWE below does exactly what I want via the TypsetInBlueOnlyIfCurrentColorIsBlack macro:



enter image description here



TypsetInBlueOnlyIfCurrentColorIsBlack is intended to change the color of its parameter to blue, only if the current color is black. Otherwise, the current color is to be used.



Questions:




  • I expected that xcolor would provide a macro to do this, but was not able to locate it. Thus, wondering if there any obvious problems with this approach, or is there an official interface that is provided.


References:




  • This solution is adapted from How to get a textual representation of the current color?
    .


Code:



documentclass{article}
usepackage{xcolor}
usepackage{xstring}

%% At this point the default color is black so save that.
edefBlackColor{csnamestringcolor@.endcsname}

makeatletter
newcommand{@CurrentColor}{}% Make sure we are not using an existing macro
newcommand*{TypsetInBlueOnlyIfCurrentColorIsBlack}[1]{%
edef@CurrentColor{csnamestringcolor@.endcsname}% Get current color
IfStrEq{@CurrentColor}{BlackColor}{%
{bfseriesttfamilytextcolor{blue}{#1}}% current color IS black
}{%
{bfseriesttfamily#1}% current color is NOT black
}%
}
makeatother

begin{document}
Following should be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}.

color{red}
Following should be in red:
TypsetInBlueOnlyIfCurrentColorIsBlack{red}.

color{blue}
Following should also be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}.
end{document}









share|improve this question













The MWE below does exactly what I want via the TypsetInBlueOnlyIfCurrentColorIsBlack macro:



enter image description here



TypsetInBlueOnlyIfCurrentColorIsBlack is intended to change the color of its parameter to blue, only if the current color is black. Otherwise, the current color is to be used.



Questions:




  • I expected that xcolor would provide a macro to do this, but was not able to locate it. Thus, wondering if there any obvious problems with this approach, or is there an official interface that is provided.


References:




  • This solution is adapted from How to get a textual representation of the current color?
    .


Code:



documentclass{article}
usepackage{xcolor}
usepackage{xstring}

%% At this point the default color is black so save that.
edefBlackColor{csnamestringcolor@.endcsname}

makeatletter
newcommand{@CurrentColor}{}% Make sure we are not using an existing macro
newcommand*{TypsetInBlueOnlyIfCurrentColorIsBlack}[1]{%
edef@CurrentColor{csnamestringcolor@.endcsname}% Get current color
IfStrEq{@CurrentColor}{BlackColor}{%
{bfseriesttfamilytextcolor{blue}{#1}}% current color IS black
}{%
{bfseriesttfamily#1}% current color is NOT black
}%
}
makeatother

begin{document}
Following should be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}.

color{red}
Following should be in red:
TypsetInBlueOnlyIfCurrentColorIsBlack{red}.

color{blue}
Following should also be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}.
end{document}






color






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Dec 15 '18 at 22:09









Peter GrillPeter Grill

164k25437748




164k25437748








  • 2




    color stores the current colour in current@color. So you could do usepackage{xcolor}{color{black}globalletmy@black@colorcurrent@color}newcommand*ifblack{ifxmy@black@colorcurrent@color}.
    – Skillmon
    Dec 15 '18 at 22:20










  • @Skillmon Better yet: sbox0{color{black}globalletmy@black@colorcurrent@color} so no whatsit is added to the main vertical list.
    – egreg
    Dec 16 '18 at 0:00














  • 2




    color stores the current colour in current@color. So you could do usepackage{xcolor}{color{black}globalletmy@black@colorcurrent@color}newcommand*ifblack{ifxmy@black@colorcurrent@color}.
    – Skillmon
    Dec 15 '18 at 22:20










  • @Skillmon Better yet: sbox0{color{black}globalletmy@black@colorcurrent@color} so no whatsit is added to the main vertical list.
    – egreg
    Dec 16 '18 at 0:00








2




2




color stores the current colour in current@color. So you could do usepackage{xcolor}{color{black}globalletmy@black@colorcurrent@color}newcommand*ifblack{ifxmy@black@colorcurrent@color}.
– Skillmon
Dec 15 '18 at 22:20




color stores the current colour in current@color. So you could do usepackage{xcolor}{color{black}globalletmy@black@colorcurrent@color}newcommand*ifblack{ifxmy@black@colorcurrent@color}.
– Skillmon
Dec 15 '18 at 22:20












@Skillmon Better yet: sbox0{color{black}globalletmy@black@colorcurrent@color} so no whatsit is added to the main vertical list.
– egreg
Dec 16 '18 at 0:00




@Skillmon Better yet: sbox0{color{black}globalletmy@black@colorcurrent@color} so no whatsit is added to the main vertical list.
– egreg
Dec 16 '18 at 0:00










1 Answer
1






active

oldest

votes


















8














An interface? Use expl3, of course!



With storecolor you can store the representation of the colors you need to do comparison with.



I define a generic comparison command and also yours as a special case.



At begin document each color in the list passed to storecolors and also black are converted in the internal representation and stored in a property list. This is for greater efficiency and not actually necessary: it saves several steps in the evaluation.



The main command converts the current color in the internal representation and compares it with the color given as the first argument (only named colors, but this could be generalized). If the test returns true, the color specified as second argument is used to print the third argument; otherwise no color change is performed.



documentclass{article}
usepackage{xcolor}
usepackage{xparse}

ExplSyntaxOn
NewDocumentCommand{perhapschangecolor}{mmm}
{% #1 = color to compare with current
% #2 = color to use if match
% #3 = text
peter_color_change:nnn { #1 } { #2 } { #3 }
}
% the same but with black and blue preset
NewDocumentCommand{TypsetInBlueOnlyIfCurrentColorIsBlack}{m}
{
perhapschangecolor{black}{blue}{#1}
}
NewDocumentCommand{storecolors}{m}
{% black is always stored
AtBeginDocument { peter_color_store:n { black,#1 } }
}

prop_new:N g_peter_color_stored_prop
tl_new:N l__peter_color_current_tl

cs_new:Nn peter_color_store:n
{
hbox_set:Nn l_tmpa_box
{
clist_map_inline:nn { #1 }
{
color{##1}
driver_color_pickup:N l_tmpa_tl
prop_gput:NnV g_peter_color_stored_prop { ##1 } l_tmpa_tl
}
}
}

cs_new_protected:Nn peter_color_change:nnn
{
driver_color_pickup:N l__peter_color_current_tl
prop_if_in:NnTF g_peter_color_stored_prop { #1 }
{% more efficient test
str_if_eq:eeTF
{ l__peter_color_current_tl }
{ prop_item:Nn g_peter_color_stored_prop { #1 } }
{ textcolor{#2}{#3} }
{ #3 }
}
{
hbox_set:Nn l_tmpa_box
{
color{#1}
driver_color_pickup:N l_tmpa_tl
tl_gset_eq:NN g_tmpa_tl l_tmpa_tl
}
driver_color_pickup:N l_tmpa_tl
str_if_eq:eeTF { g_tmpa_tl } { l_tmpa_tl }
{ textcolor{#2}{#3} }
{ #3 }
}
}
ExplSyntaxOff

storecolors{red!60}

begin{document}

Following should be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}

color{red}
Following should be in red:
TypsetInBlueOnlyIfCurrentColorIsBlack{red}

color{blue}
Following should be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}

color{black}
Following should be in pale red:
perhapschangecolor{black}{red!60}{red!60}

color{red!60}
Following should be in pale red:
perhapschangecolor{black}{red!60}{red!60}

color{blue}
Following should be in blue:
perhapschangecolor{black}{red!60}{blue}

% blue has not been stored, but the test succeeds as well
Following should be in pale red:
perhapschangecolor{blue}{red!60}{red!60}

end{document}


enter image description here






share|improve this answer





















  • In clist_map_inline:nn in peter_color_store:n you're missing an additional group around color{##1}.
    – Skillmon
    Dec 16 '18 at 8:37










  • @Skillmon It's not necessary, as the code is executed inside a box being built and then unused.
    – egreg
    Dec 16 '18 at 10:46










  • I'd still do so, just to not lead to bad practise. Somebody not knowing the limitations and seeing this code might write faulty code because he thinks it's generally safe to use it inside a box.
    – Skillmon
    Dec 16 '18 at 13:01











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "85"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f466026%2ftest-if-current-color-is-black%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









8














An interface? Use expl3, of course!



With storecolor you can store the representation of the colors you need to do comparison with.



I define a generic comparison command and also yours as a special case.



At begin document each color in the list passed to storecolors and also black are converted in the internal representation and stored in a property list. This is for greater efficiency and not actually necessary: it saves several steps in the evaluation.



The main command converts the current color in the internal representation and compares it with the color given as the first argument (only named colors, but this could be generalized). If the test returns true, the color specified as second argument is used to print the third argument; otherwise no color change is performed.



documentclass{article}
usepackage{xcolor}
usepackage{xparse}

ExplSyntaxOn
NewDocumentCommand{perhapschangecolor}{mmm}
{% #1 = color to compare with current
% #2 = color to use if match
% #3 = text
peter_color_change:nnn { #1 } { #2 } { #3 }
}
% the same but with black and blue preset
NewDocumentCommand{TypsetInBlueOnlyIfCurrentColorIsBlack}{m}
{
perhapschangecolor{black}{blue}{#1}
}
NewDocumentCommand{storecolors}{m}
{% black is always stored
AtBeginDocument { peter_color_store:n { black,#1 } }
}

prop_new:N g_peter_color_stored_prop
tl_new:N l__peter_color_current_tl

cs_new:Nn peter_color_store:n
{
hbox_set:Nn l_tmpa_box
{
clist_map_inline:nn { #1 }
{
color{##1}
driver_color_pickup:N l_tmpa_tl
prop_gput:NnV g_peter_color_stored_prop { ##1 } l_tmpa_tl
}
}
}

cs_new_protected:Nn peter_color_change:nnn
{
driver_color_pickup:N l__peter_color_current_tl
prop_if_in:NnTF g_peter_color_stored_prop { #1 }
{% more efficient test
str_if_eq:eeTF
{ l__peter_color_current_tl }
{ prop_item:Nn g_peter_color_stored_prop { #1 } }
{ textcolor{#2}{#3} }
{ #3 }
}
{
hbox_set:Nn l_tmpa_box
{
color{#1}
driver_color_pickup:N l_tmpa_tl
tl_gset_eq:NN g_tmpa_tl l_tmpa_tl
}
driver_color_pickup:N l_tmpa_tl
str_if_eq:eeTF { g_tmpa_tl } { l_tmpa_tl }
{ textcolor{#2}{#3} }
{ #3 }
}
}
ExplSyntaxOff

storecolors{red!60}

begin{document}

Following should be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}

color{red}
Following should be in red:
TypsetInBlueOnlyIfCurrentColorIsBlack{red}

color{blue}
Following should be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}

color{black}
Following should be in pale red:
perhapschangecolor{black}{red!60}{red!60}

color{red!60}
Following should be in pale red:
perhapschangecolor{black}{red!60}{red!60}

color{blue}
Following should be in blue:
perhapschangecolor{black}{red!60}{blue}

% blue has not been stored, but the test succeeds as well
Following should be in pale red:
perhapschangecolor{blue}{red!60}{red!60}

end{document}


enter image description here






share|improve this answer





















  • In clist_map_inline:nn in peter_color_store:n you're missing an additional group around color{##1}.
    – Skillmon
    Dec 16 '18 at 8:37










  • @Skillmon It's not necessary, as the code is executed inside a box being built and then unused.
    – egreg
    Dec 16 '18 at 10:46










  • I'd still do so, just to not lead to bad practise. Somebody not knowing the limitations and seeing this code might write faulty code because he thinks it's generally safe to use it inside a box.
    – Skillmon
    Dec 16 '18 at 13:01
















8














An interface? Use expl3, of course!



With storecolor you can store the representation of the colors you need to do comparison with.



I define a generic comparison command and also yours as a special case.



At begin document each color in the list passed to storecolors and also black are converted in the internal representation and stored in a property list. This is for greater efficiency and not actually necessary: it saves several steps in the evaluation.



The main command converts the current color in the internal representation and compares it with the color given as the first argument (only named colors, but this could be generalized). If the test returns true, the color specified as second argument is used to print the third argument; otherwise no color change is performed.



documentclass{article}
usepackage{xcolor}
usepackage{xparse}

ExplSyntaxOn
NewDocumentCommand{perhapschangecolor}{mmm}
{% #1 = color to compare with current
% #2 = color to use if match
% #3 = text
peter_color_change:nnn { #1 } { #2 } { #3 }
}
% the same but with black and blue preset
NewDocumentCommand{TypsetInBlueOnlyIfCurrentColorIsBlack}{m}
{
perhapschangecolor{black}{blue}{#1}
}
NewDocumentCommand{storecolors}{m}
{% black is always stored
AtBeginDocument { peter_color_store:n { black,#1 } }
}

prop_new:N g_peter_color_stored_prop
tl_new:N l__peter_color_current_tl

cs_new:Nn peter_color_store:n
{
hbox_set:Nn l_tmpa_box
{
clist_map_inline:nn { #1 }
{
color{##1}
driver_color_pickup:N l_tmpa_tl
prop_gput:NnV g_peter_color_stored_prop { ##1 } l_tmpa_tl
}
}
}

cs_new_protected:Nn peter_color_change:nnn
{
driver_color_pickup:N l__peter_color_current_tl
prop_if_in:NnTF g_peter_color_stored_prop { #1 }
{% more efficient test
str_if_eq:eeTF
{ l__peter_color_current_tl }
{ prop_item:Nn g_peter_color_stored_prop { #1 } }
{ textcolor{#2}{#3} }
{ #3 }
}
{
hbox_set:Nn l_tmpa_box
{
color{#1}
driver_color_pickup:N l_tmpa_tl
tl_gset_eq:NN g_tmpa_tl l_tmpa_tl
}
driver_color_pickup:N l_tmpa_tl
str_if_eq:eeTF { g_tmpa_tl } { l_tmpa_tl }
{ textcolor{#2}{#3} }
{ #3 }
}
}
ExplSyntaxOff

storecolors{red!60}

begin{document}

Following should be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}

color{red}
Following should be in red:
TypsetInBlueOnlyIfCurrentColorIsBlack{red}

color{blue}
Following should be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}

color{black}
Following should be in pale red:
perhapschangecolor{black}{red!60}{red!60}

color{red!60}
Following should be in pale red:
perhapschangecolor{black}{red!60}{red!60}

color{blue}
Following should be in blue:
perhapschangecolor{black}{red!60}{blue}

% blue has not been stored, but the test succeeds as well
Following should be in pale red:
perhapschangecolor{blue}{red!60}{red!60}

end{document}


enter image description here






share|improve this answer





















  • In clist_map_inline:nn in peter_color_store:n you're missing an additional group around color{##1}.
    – Skillmon
    Dec 16 '18 at 8:37










  • @Skillmon It's not necessary, as the code is executed inside a box being built and then unused.
    – egreg
    Dec 16 '18 at 10:46










  • I'd still do so, just to not lead to bad practise. Somebody not knowing the limitations and seeing this code might write faulty code because he thinks it's generally safe to use it inside a box.
    – Skillmon
    Dec 16 '18 at 13:01














8












8








8






An interface? Use expl3, of course!



With storecolor you can store the representation of the colors you need to do comparison with.



I define a generic comparison command and also yours as a special case.



At begin document each color in the list passed to storecolors and also black are converted in the internal representation and stored in a property list. This is for greater efficiency and not actually necessary: it saves several steps in the evaluation.



The main command converts the current color in the internal representation and compares it with the color given as the first argument (only named colors, but this could be generalized). If the test returns true, the color specified as second argument is used to print the third argument; otherwise no color change is performed.



documentclass{article}
usepackage{xcolor}
usepackage{xparse}

ExplSyntaxOn
NewDocumentCommand{perhapschangecolor}{mmm}
{% #1 = color to compare with current
% #2 = color to use if match
% #3 = text
peter_color_change:nnn { #1 } { #2 } { #3 }
}
% the same but with black and blue preset
NewDocumentCommand{TypsetInBlueOnlyIfCurrentColorIsBlack}{m}
{
perhapschangecolor{black}{blue}{#1}
}
NewDocumentCommand{storecolors}{m}
{% black is always stored
AtBeginDocument { peter_color_store:n { black,#1 } }
}

prop_new:N g_peter_color_stored_prop
tl_new:N l__peter_color_current_tl

cs_new:Nn peter_color_store:n
{
hbox_set:Nn l_tmpa_box
{
clist_map_inline:nn { #1 }
{
color{##1}
driver_color_pickup:N l_tmpa_tl
prop_gput:NnV g_peter_color_stored_prop { ##1 } l_tmpa_tl
}
}
}

cs_new_protected:Nn peter_color_change:nnn
{
driver_color_pickup:N l__peter_color_current_tl
prop_if_in:NnTF g_peter_color_stored_prop { #1 }
{% more efficient test
str_if_eq:eeTF
{ l__peter_color_current_tl }
{ prop_item:Nn g_peter_color_stored_prop { #1 } }
{ textcolor{#2}{#3} }
{ #3 }
}
{
hbox_set:Nn l_tmpa_box
{
color{#1}
driver_color_pickup:N l_tmpa_tl
tl_gset_eq:NN g_tmpa_tl l_tmpa_tl
}
driver_color_pickup:N l_tmpa_tl
str_if_eq:eeTF { g_tmpa_tl } { l_tmpa_tl }
{ textcolor{#2}{#3} }
{ #3 }
}
}
ExplSyntaxOff

storecolors{red!60}

begin{document}

Following should be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}

color{red}
Following should be in red:
TypsetInBlueOnlyIfCurrentColorIsBlack{red}

color{blue}
Following should be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}

color{black}
Following should be in pale red:
perhapschangecolor{black}{red!60}{red!60}

color{red!60}
Following should be in pale red:
perhapschangecolor{black}{red!60}{red!60}

color{blue}
Following should be in blue:
perhapschangecolor{black}{red!60}{blue}

% blue has not been stored, but the test succeeds as well
Following should be in pale red:
perhapschangecolor{blue}{red!60}{red!60}

end{document}


enter image description here






share|improve this answer












An interface? Use expl3, of course!



With storecolor you can store the representation of the colors you need to do comparison with.



I define a generic comparison command and also yours as a special case.



At begin document each color in the list passed to storecolors and also black are converted in the internal representation and stored in a property list. This is for greater efficiency and not actually necessary: it saves several steps in the evaluation.



The main command converts the current color in the internal representation and compares it with the color given as the first argument (only named colors, but this could be generalized). If the test returns true, the color specified as second argument is used to print the third argument; otherwise no color change is performed.



documentclass{article}
usepackage{xcolor}
usepackage{xparse}

ExplSyntaxOn
NewDocumentCommand{perhapschangecolor}{mmm}
{% #1 = color to compare with current
% #2 = color to use if match
% #3 = text
peter_color_change:nnn { #1 } { #2 } { #3 }
}
% the same but with black and blue preset
NewDocumentCommand{TypsetInBlueOnlyIfCurrentColorIsBlack}{m}
{
perhapschangecolor{black}{blue}{#1}
}
NewDocumentCommand{storecolors}{m}
{% black is always stored
AtBeginDocument { peter_color_store:n { black,#1 } }
}

prop_new:N g_peter_color_stored_prop
tl_new:N l__peter_color_current_tl

cs_new:Nn peter_color_store:n
{
hbox_set:Nn l_tmpa_box
{
clist_map_inline:nn { #1 }
{
color{##1}
driver_color_pickup:N l_tmpa_tl
prop_gput:NnV g_peter_color_stored_prop { ##1 } l_tmpa_tl
}
}
}

cs_new_protected:Nn peter_color_change:nnn
{
driver_color_pickup:N l__peter_color_current_tl
prop_if_in:NnTF g_peter_color_stored_prop { #1 }
{% more efficient test
str_if_eq:eeTF
{ l__peter_color_current_tl }
{ prop_item:Nn g_peter_color_stored_prop { #1 } }
{ textcolor{#2}{#3} }
{ #3 }
}
{
hbox_set:Nn l_tmpa_box
{
color{#1}
driver_color_pickup:N l_tmpa_tl
tl_gset_eq:NN g_tmpa_tl l_tmpa_tl
}
driver_color_pickup:N l_tmpa_tl
str_if_eq:eeTF { g_tmpa_tl } { l_tmpa_tl }
{ textcolor{#2}{#3} }
{ #3 }
}
}
ExplSyntaxOff

storecolors{red!60}

begin{document}

Following should be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}

color{red}
Following should be in red:
TypsetInBlueOnlyIfCurrentColorIsBlack{red}

color{blue}
Following should be in blue:
TypsetInBlueOnlyIfCurrentColorIsBlack{blue}

color{black}
Following should be in pale red:
perhapschangecolor{black}{red!60}{red!60}

color{red!60}
Following should be in pale red:
perhapschangecolor{black}{red!60}{red!60}

color{blue}
Following should be in blue:
perhapschangecolor{black}{red!60}{blue}

% blue has not been stored, but the test succeeds as well
Following should be in pale red:
perhapschangecolor{blue}{red!60}{red!60}

end{document}


enter image description here







share|improve this answer












share|improve this answer



share|improve this answer










answered Dec 16 '18 at 1:04









egregegreg

710k8618883172




710k8618883172












  • In clist_map_inline:nn in peter_color_store:n you're missing an additional group around color{##1}.
    – Skillmon
    Dec 16 '18 at 8:37










  • @Skillmon It's not necessary, as the code is executed inside a box being built and then unused.
    – egreg
    Dec 16 '18 at 10:46










  • I'd still do so, just to not lead to bad practise. Somebody not knowing the limitations and seeing this code might write faulty code because he thinks it's generally safe to use it inside a box.
    – Skillmon
    Dec 16 '18 at 13:01


















  • In clist_map_inline:nn in peter_color_store:n you're missing an additional group around color{##1}.
    – Skillmon
    Dec 16 '18 at 8:37










  • @Skillmon It's not necessary, as the code is executed inside a box being built and then unused.
    – egreg
    Dec 16 '18 at 10:46










  • I'd still do so, just to not lead to bad practise. Somebody not knowing the limitations and seeing this code might write faulty code because he thinks it's generally safe to use it inside a box.
    – Skillmon
    Dec 16 '18 at 13:01
















In clist_map_inline:nn in peter_color_store:n you're missing an additional group around color{##1}.
– Skillmon
Dec 16 '18 at 8:37




In clist_map_inline:nn in peter_color_store:n you're missing an additional group around color{##1}.
– Skillmon
Dec 16 '18 at 8:37












@Skillmon It's not necessary, as the code is executed inside a box being built and then unused.
– egreg
Dec 16 '18 at 10:46




@Skillmon It's not necessary, as the code is executed inside a box being built and then unused.
– egreg
Dec 16 '18 at 10:46












I'd still do so, just to not lead to bad practise. Somebody not knowing the limitations and seeing this code might write faulty code because he thinks it's generally safe to use it inside a box.
– Skillmon
Dec 16 '18 at 13:01




I'd still do so, just to not lead to bad practise. Somebody not knowing the limitations and seeing this code might write faulty code because he thinks it's generally safe to use it inside a box.
– Skillmon
Dec 16 '18 at 13:01


















draft saved

draft discarded




















































Thanks for contributing an answer to TeX - LaTeX Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f466026%2ftest-if-current-color-is-black%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

If I really need a card on my start hand, how many mulligans make sense? [duplicate]

Alcedinidae

Can an atomic nucleus contain both particles and antiparticles? [duplicate]