Test if Current Color is Black











up vote
10
down vote

favorite
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


















  • 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 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 at 0:00















up vote
10
down vote

favorite
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


















  • 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 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 at 0:00













up vote
10
down vote

favorite
2









up vote
10
down vote

favorite
2






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 at 22:09









Peter Grill

163k25433745




163k25433745








  • 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 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 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 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 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 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 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 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 at 0:00










1 Answer
1






active

oldest

votes

















up vote
6
down vote













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 at 8:37










  • @Skillmon It's not necessary, as the code is executed inside a box being built and then unused.
    – egreg
    Dec 16 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 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








up vote
6
down vote













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 at 8:37










  • @Skillmon It's not necessary, as the code is executed inside a box being built and then unused.
    – egreg
    Dec 16 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 at 13:01















up vote
6
down vote













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 at 8:37










  • @Skillmon It's not necessary, as the code is executed inside a box being built and then unused.
    – egreg
    Dec 16 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 at 13:01













up vote
6
down vote










up vote
6
down vote









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 at 1:04









egreg

706k8618773159




706k8618773159












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










  • @Skillmon It's not necessary, as the code is executed inside a box being built and then unused.
    – egreg
    Dec 16 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 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 at 8:37










  • @Skillmon It's not necessary, as the code is executed inside a box being built and then unused.
    – egreg
    Dec 16 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 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 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 at 8:37












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




@Skillmon It's not necessary, as the code is executed inside a box being built and then unused.
– egreg
Dec 16 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 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 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]