TeX - LaTeX Asked by Hushus46 on June 3, 2021
I am trying to make it so when I define tcolorbox theorem environments, that I dont have to enter two extra curly braces after begin{environment}{}{}
.
If I don’t put the curly braces, the first two letters of text within the environment get absorbed within where the curly braces used to be.
The problem might arise from the definition of the tcbtheorem?
See MWE below
documentclass[12pt]{report}
usepackage[most]{tcolorbox}
newtcbtheorem[number within = chapter]{dfn}{Definition}%
{
enhanced,
before title = {stepcounter{dfn}},
colback=blue!10,
colframe=blue!35!black,
fonttitle=bfseries,
top=3mm,
attach boxed title to top left={xshift = 5mm, yshift=-1.5mm},
boxed title style = {colback=blue!35!black}
}{dfn}
newcounter{dfn}
begin{document}
begin{dfn}
abc
end{dfn}
begin{dfn}{}{}
abc
end{dfn}
end{document}
An environment defined with newtcbtheorem
indeed requires two mandatory arguments:
begin{dfn}{}{}
Text of the definition
end{dfn}
The first argument is for the title, the second is for the label. With a call such as
begin{dfn}{Nice one}{}
Text of the definition
end{dfn}
the title would be set to “Nice one” and there would be no label. With
begin{dfn}{Nice one}{nice}
Text of the definition
end{dfn}
you can refer to the number of the definition by ref{dfn:nice}
(the prefix before the colon is the last argument for newtcbtheorem
.
You can also leave the title empty and set a label
begin{dfn}{}{nice}
Text of the definition
end{dfn}
That's the way it is.
You might define a wrapper around such theorems so you can use a different and, in my opinion, handier syntax.
documentclass[12pt]{report}
usepackage[most]{tcolorbox}
newtcbtheorem[number within = chapter]{dfninner}{Definition}%
{
enhanced,
before title = {stepcounter{dfn}},
colback=blue!10,
colframe=blue!35!black,
fonttitle=bfseries,
top=3mm,
attach boxed title to top left={xshift = 5mm, yshift=-1.5mm},
boxed title style = {colback=blue!35!black}
}{dfn}
newcounter{dfn}
ExplSyntaxOn
NewDocumentEnvironment{dfn}{O{}}
{
keys_set:nn { hushus/tcb } { #1 }
hushus_tcb_begin:nVV {dfninner} l__hushus_tcb_title_tl l__hushus_tcb_label_tl
}
{
end{dfninner}
}
cs_new_protected:Nn hushus_tcb_begin:nnn
{
begin{#1}{#2}{#3}
}
cs_generate_variant:Nn hushus_tcb_begin:nnn { nVV }
keys_define:nn { hushus/tcb }
{
title .tl_set:N = l__hushus_tcb_title_tl,
label .tl_set:N = l__hushus_tcb_label_tl,
}
ExplSyntaxOff
begin{document}
begin{dfn}
abc
end{dfn}
begin{dfn}[title=Nice,label=nice]
abc
end{dfn}
ref{dfn:nice}
end{document}
An abstraction of the previous code that allows to use the standard tcolorbox
syntax and takes care of the modifications for all environments you want to define.
documentclass[12pt]{report}
usepackage[most]{tcolorbox}
ExplSyntaxOn
NewDocumentCommand{betternewtcbtheorem}{O{}mmmm}
{
newtcbtheorem[#1]{#2inner}{#3}{#4}{#5}
NewDocumentEnvironment{#2}{O{}}
{
keys_set:nn { hushus/tcb } { ##1 }
hushus_tcb_begin:nVV {#2inner} l__hushus_tcb_title_tl l__hushus_tcb_label_tl
}
{
end{#2inner}
}
cs_if_exist:cF { c@#5} { newcounter{#5} }
}
cs_new_protected:Nn hushus_tcb_begin:nnn
{
begin{#1}{#2}{#3}
}
cs_generate_variant:Nn hushus_tcb_begin:nnn { nVV }
keys_define:nn { hushus/tcb }
{
title .tl_set:N = l__hushus_tcb_title_tl,
label .tl_set:N = l__hushus_tcb_label_tl,
}
ExplSyntaxOff
betternewtcbtheorem[number within = chapter]{dfn}{Definition}%
{
enhanced,
before title = {stepcounter{dfn}},
colback=blue!10,
colframe=blue!35!black,
fonttitle=bfseries,
top=3mm,
attach boxed title to top left={xshift = 5mm, yshift=-1.5mm},
boxed title style = {colback=blue!35!black}
}{dfn}
begin{document}
begin{dfn}
abc
end{dfn}
begin{dfn}[title=Nice,label=nice]
abc
end{dfn}
ref{dfn:nice}
end{document}
What's happening? The idea is that betternewtcbtheorem
defines an “inner” environment that will be called by the one with the desired name.
In the example above, the desired name is dfn
, so first we call newtcolorbox
passing the arguments, but with inner
appended to the name. Next the dfn
environment is defined, taking an optional argument that should contain something with key-value syntax.
The allowed keys are title
and label
. When dfn
is called, we pass the values in the proper place. Since these values are stored in token list variables, I define a function
hushus_tcb_begin:nnn
that will call begin{dfninner}{<title>}{<label>}
, but I need to pass the contents of two variables, so this is the place for the variant
hushus_tcb_begin:nVV
that takes the first argument braced as usual, but the other two should be token list variables, whose content is passed to the main function as if they were braced arguments.
Final touch: a counter is defined if not previously existing, based on the last argument to newtcbtheorem
.
Correct answer by egreg on June 3, 2021
You can define a new environment with optional arguments, and check if the values are provided.
documentclass[12pt]{report}
usepackage{xparse}
usepackage[most]{tcolorbox}
newtcbtheorem[number within = chapter]{dfn}{Definition}%
{
enhanced,
before title = {stepcounter{dfn}},
colback=blue!10,
colframe=blue!35!black,
fonttitle=bfseries,
top=3mm,
attach boxed title to top left={xshift = 5mm, yshift=-1.5mm},
boxed title style = {colback=blue!35!black}
}{dfn}
newcounter{dfn}
NewDocumentEnvironment{DFN}{d()d()}{begin{dfn}{IfValueT{#1}{#1}}{IfValueT{#2}{#2}}}{end{dfn}}
begin{document}
begin{dfn}
abc
end{dfn}
begin{DFN}
abc
end{DFN}
begin{dfn}{}{}
abc
end{dfn}
begin{DFN}(q)(s)
abc
end{DFN}
end{document}
Answered by NBur on June 3, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP