TeX - LaTeX Asked on July 27, 2021
I need to define an environment inside which I can simply do begin{some string}some stuffend{some string}
with arbitrary strings, and have it process these as environments (which output e.g. textbf{some string:} somestuff
). The environments should also accept an optional parameter that modifies their behavior.
Preexisting environments like enumerate or itemize should still work inside my environment.
I can achieve most of this with the following code:
makeatletter
defifEqString#1#2{defcsa{#1}defcsb{#2}ifxcsacsb }
defifUnDefinedCs#1{expandafter ifxcsname#1endcsnamerelax}
letold@begin=begin
defnew@begin{ifx[next expandafternewXX@begin else expandafternewX@begin fi}
defnewX@begin#1{ifUnDefinedCs{#1}newZ@begin{#1}elseold@begin{#1} fi}
defnewZ@begin#1{head@font{#1}parnewenvironment{#1}{lethead@font=textit}{relax}old@begin{#1}}
defnewXX@begin[#1]#2{ifEqString{#1}{plain}--else{#1}fi {#2}parnewenvironment{#2}{lethead@font=textit}{relax}old@begin{#2}}
newenvironment{myenvironment}{begingroup%
lethead@font=textbf
defbegin{futureletnextnew@begin}
}{endgroup}
makeatother
However, this breaks preexisting environments like tabular
that require parameters to be given. Is there a better way to code this that doesn’t break these?
I think you're going to have to do some heavy lifting here. A simple patching of begin
won't do the job because begin
has to be able to read optional and required arguments on occasion. You're much better off just declaring a custom environment for your needs. You can even keep your typing concise by giving it a nice short name, e.g., (assuming xparse
is available):
NewDocumentEnvironment{||}{ m o }{%
IfNoValueTF{#2}{%
No optional argument
}%
{%
Optional argument #2
}%
textbf{#1:}}%
{} % We don't need to do anything at the end
begin{||}{some string} some stuff end{||}
But if you don't want to do that, declare the command that will handle your special environment:
NewDocumentCommand{UndeclaredEnvironment}{ m o }{...}
This will take the name of the undeclared environment as its first required argument and then an optional argument and you can define it like we did the environment above.
Now comes surgery time. Before we go any further, let me emphasize that this is a bad idea. texdoc source2e
will give you the annotated source code for LaTeX. The definition for begin
appears on page 473 in the D ltmiscen.dtx section:
DeclareRobustCommand*begin[1]{%
UseHook{env/#1/before}%
@ifundefined{#1}%
{defreserved@a{@latex@error{Environment #1 undefined}@eha}}% ❶
{defreserved@a{def@currenvir{#1}%
edef@currenvline{on@line}%
@execute@begin@hook{#1}%
csname #1endcsname}}%
@ignorefalse
begingroup@endpefalsereserved@a}
The line we're interested in is the one I've marked with ❶. You'll want to copy the above to a new command, say, BadIdeaBegin
(with makeatletter
active) and change that line to read:
{defreserved@a{def@currenvir{#1}%
edef@currenvline{on@line}%
@execute@begin@hook{#1}%
UndeclaredEnvironment{#1}}}%
Then you can have your environment be
newenvironment{VeryBadIdea}{letbeginBadIdeaBegin}{}
And things will work the way you think you want them to work.
Correct answer by Don Hosek on July 27, 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