TeX - LaTeX Asked by Alois Pichler on June 1, 2021
A command can be employed as an environment.
The macro
newcommand{rev}[2][blue]{{color{#1}#2}}
simply colors its argument, for example.
Why does the corresponding environment not color the entire content?
begin{document}
black % is correct
rev{in blue} rev[red]{in red} % correct
black % correct
begin{rev}in blueend{rev}% only first letter is blue
begin{rev}[red] % only first letter is red
in red
end{rev}
black again % black again
end{document}
As well, rev[normalcolor]{text}
should work fine.
It is possible to check whether the macro is used as an environment or as a normal command by checking against @currenvir
. The following uses this to either call color
(which will colour the entire contents of the environment), or textcolor
(which will only colour the mandatory argument).
documentclass[]{article}
usepackage[]{color}
makeatletter
newcommandrev[1][blue]
{%
begingroup
deftmp{rev}%
expandafter
endgroup
ifxtmp@currenvir
expandaftercolor
else
expandaftertextcolor
fi
{#1}%
}
makeatother
begin{document}
black % is correct
rev{in blue} rev[red]{in red} % correct
black % correct
begin{rev}in blueend{rev} % only first letter is blue
begin{rev}[red] % only first letter is red
in red%
end{rev}
black again % black again
end{document}
Note that this isn't fool-proof. A usage such as begin{rev}abcrev[red]{def}ghiend{rev}
will result in abc
being blue, and defghi
being red.
A perhaps better way to check whether rev
is used as an environment is to use LaTeX's hook mechanism to set a boolean that indicates that the current rev
is an environment (and let the environment version set the boolean back to false). This would also work for cases such as begin{rev}abcrev[red]{def}ghiend{rev}
.
documentclass[]{article}
usepackage[]{color}
makeatletter
newififrev@inenv
ifdefinedAddToHook
AddToHook{env/rev/begin}{rev@inenvtrue}
else
usepackage{etoolbox}
AtBeginEnvironment{rev}{rev@inenvtrue}
fi
newcommandrev[1][blue]
{%
ifrev@inenv
rev@inenvfalse
expandaftercolor
else
expandaftertextcolor
fi
{#1}%
}
makeatother
begin{document}
black % is correct
rev{in blue} rev[red]{in red} % correct
black % correct
begin{rev}in blueend{rev} % only first letter is blue
begin{rev}[red] % only first letter is red
in redrev[green]{test}ed%
end{rev}
black again % black again
end{document}
(I made an edit which checks whether AddToHook
is available, and if not falls back to etoolbox
)
Correct answer by Skillmon on June 1, 2021
begin{rev}[red] % only first letter is red
in red
end{rev}
is more or less
begingrouprev[red]
in red
relaxendgroup
which is equivalent to
begingrouprev[red]{i}%
n red
relaxendgroup
By the built in rules of parsing for tex macro arguments.
If you want to define an environment where the body of the environment acts as a macro parameter, use NewDocumentEnvironment
and a b
argument. This requires the xparse
package in older latex fromats but is built in to current releases.
Of course for the specific example of color
no argument is needed, just use color{red}
and the scope of the colour change will end at the end of the environment.
Answered by David Carlisle on June 1, 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