csname in newenviromentWhy can't the end code of an environment contain an argument?Setup a newenviroment for figure with includegraphics and captionCompiler Error when Creating a Macro/EnvironmentDefinition of a macro with multiple arguments and usage of csname
The art of clickbait captions
Are these reasonable traits for someone with autism?
Employer asking for online access to bank account - Is this a scam?
Is it true that cut time means "play twice as fast as written"?
How to use libraries with delays inside within a time critical STM32 HAL application?
What to keep in mind when telling an aunt how wrong her actions are, without creating further family conflict?
Is real public IP Address hidden when using a system wide proxy in Windows 10?
Grammar Question Regarding "Are the" or "Is the" When Referring to Something that May or May not be Plural
Using credit/debit card details vs swiping a card in a payment (credit card) terminal
Have 1.5% of all nuclear reactors ever built melted down?
How to illustrate the Mean Value theorem?
Make 24 using exactly three 3s
Any advice on creating fictional locations in real places when writing historical fiction?
Why aren't space telescopes put in GEO?
C++ forcing function parameter evalution order
using Leibniz rule to solve definite integral
What is a Centaur Thief's climbing speed?
Plot twist where the antagonist wins
What are the mechanical differences between the uncommon Medallion of Thoughts and the rare Potion of Mind Reading?
Who will lead the country until there is a new Tory leader?
Can I tell a prospective employee that everyone in the team is leaving?
Inconsistent results from Wolfram Could
Count rotary dial pulses in a phone number (including letters)
Teacher help me explain this to my students
csname in newenviroment
Why can't the end code of an environment contain an argument?Setup a newenviroment for figure with includegraphics and captionCompiler Error when Creating a Macro/EnvironmentDefinition of a macro with multiple arguments and usage of csname
I defined a newenvironment with this code (sample):
documentclassarticle
usepackage[utf8]inputenc
usepackageamsthm
newenvironmentmyEnv[1][default]
pushQED#1
expandaftercsname x#1 endcsname
expandaftercsname endxpopQED endcsname
newenvironmentxdefault
begindocument
beginmyEnv
endmyEnv
enddocument
I need this for some stuff later to call a specific environment using the argument. But I get the following error in Overleaf:
Missing endcsname inserted.
<to be read again>
begingroup
l.35 endmyEnv
The control sequence marked <to be read again> should
not appear between csname and endcsname.
-----------
Extra endcsname.
endmyEnv ...after csname endxpopQED endcsname
l.35 endmyEnv
I'm ignoring this, since I wasn't doing a csname.
As far as I can tell, the csname/endcsname's should be correct, I don't see an error, so I have no idea what causes this. When I searched the error I only found topics that were unrealated to my example.
Does someone know how to fix this?
environments
add a comment |
I defined a newenvironment with this code (sample):
documentclassarticle
usepackage[utf8]inputenc
usepackageamsthm
newenvironmentmyEnv[1][default]
pushQED#1
expandaftercsname x#1 endcsname
expandaftercsname endxpopQED endcsname
newenvironmentxdefault
begindocument
beginmyEnv
endmyEnv
enddocument
I need this for some stuff later to call a specific environment using the argument. But I get the following error in Overleaf:
Missing endcsname inserted.
<to be read again>
begingroup
l.35 endmyEnv
The control sequence marked <to be read again> should
not appear between csname and endcsname.
-----------
Extra endcsname.
endmyEnv ...after csname endxpopQED endcsname
l.35 endmyEnv
I'm ignoring this, since I wasn't doing a csname.
As far as I can tell, the csname/endcsname's should be correct, I don't see an error, so I have no idea what causes this. When I searched the error I only found topics that were unrealated to my example.
Does someone know how to fix this?
environments
My guess would be that thepopQED
withincsname ... endcsname
is a bit too much for LaTeX. I presumepopQED
does not expand to simple text, so LaTeX fails to make sense of it as part of a control sequence name. Maybe you just meancsname endx#1endcsnamepopQED
? I'm also not quite sure if theexpandafter
s are needed and the trailing space after#1
incsname x#1 endcsname
might be too much. (But this is all speculation without a full example document where I can verify the definitions involved.)
– moewe
May 19 at 19:56
@moewe Using pushQED was something I found searching for how to pass arguments to the end part. The space after #1 was from searching the error, removing them doesn't change that. moving popQED behind endscname causes the error to go, but then it prints 'default' and doesn't call endxdefault
– Thorsten Schmitz
May 19 at 20:01
Ah, I see. I don't thinkpopQED
andpushQED
can help you here. Trydeftssavedarg#1
andcsname endxtssavedargendcsname
instead.
– moewe
May 19 at 20:05
expandaftercsname x
expandsx
which is not expandable, so theexpandafter
is doing nothing.
– David Carlisle
May 19 at 20:30
add a comment |
I defined a newenvironment with this code (sample):
documentclassarticle
usepackage[utf8]inputenc
usepackageamsthm
newenvironmentmyEnv[1][default]
pushQED#1
expandaftercsname x#1 endcsname
expandaftercsname endxpopQED endcsname
newenvironmentxdefault
begindocument
beginmyEnv
endmyEnv
enddocument
I need this for some stuff later to call a specific environment using the argument. But I get the following error in Overleaf:
Missing endcsname inserted.
<to be read again>
begingroup
l.35 endmyEnv
The control sequence marked <to be read again> should
not appear between csname and endcsname.
-----------
Extra endcsname.
endmyEnv ...after csname endxpopQED endcsname
l.35 endmyEnv
I'm ignoring this, since I wasn't doing a csname.
As far as I can tell, the csname/endcsname's should be correct, I don't see an error, so I have no idea what causes this. When I searched the error I only found topics that were unrealated to my example.
Does someone know how to fix this?
environments
I defined a newenvironment with this code (sample):
documentclassarticle
usepackage[utf8]inputenc
usepackageamsthm
newenvironmentmyEnv[1][default]
pushQED#1
expandaftercsname x#1 endcsname
expandaftercsname endxpopQED endcsname
newenvironmentxdefault
begindocument
beginmyEnv
endmyEnv
enddocument
I need this for some stuff later to call a specific environment using the argument. But I get the following error in Overleaf:
Missing endcsname inserted.
<to be read again>
begingroup
l.35 endmyEnv
The control sequence marked <to be read again> should
not appear between csname and endcsname.
-----------
Extra endcsname.
endmyEnv ...after csname endxpopQED endcsname
l.35 endmyEnv
I'm ignoring this, since I wasn't doing a csname.
As far as I can tell, the csname/endcsname's should be correct, I don't see an error, so I have no idea what causes this. When I searched the error I only found topics that were unrealated to my example.
Does someone know how to fix this?
environments
environments
edited May 19 at 19:58
Thorsten Schmitz
asked May 19 at 19:50
Thorsten SchmitzThorsten Schmitz
112
112
My guess would be that thepopQED
withincsname ... endcsname
is a bit too much for LaTeX. I presumepopQED
does not expand to simple text, so LaTeX fails to make sense of it as part of a control sequence name. Maybe you just meancsname endx#1endcsnamepopQED
? I'm also not quite sure if theexpandafter
s are needed and the trailing space after#1
incsname x#1 endcsname
might be too much. (But this is all speculation without a full example document where I can verify the definitions involved.)
– moewe
May 19 at 19:56
@moewe Using pushQED was something I found searching for how to pass arguments to the end part. The space after #1 was from searching the error, removing them doesn't change that. moving popQED behind endscname causes the error to go, but then it prints 'default' and doesn't call endxdefault
– Thorsten Schmitz
May 19 at 20:01
Ah, I see. I don't thinkpopQED
andpushQED
can help you here. Trydeftssavedarg#1
andcsname endxtssavedargendcsname
instead.
– moewe
May 19 at 20:05
expandaftercsname x
expandsx
which is not expandable, so theexpandafter
is doing nothing.
– David Carlisle
May 19 at 20:30
add a comment |
My guess would be that thepopQED
withincsname ... endcsname
is a bit too much for LaTeX. I presumepopQED
does not expand to simple text, so LaTeX fails to make sense of it as part of a control sequence name. Maybe you just meancsname endx#1endcsnamepopQED
? I'm also not quite sure if theexpandafter
s are needed and the trailing space after#1
incsname x#1 endcsname
might be too much. (But this is all speculation without a full example document where I can verify the definitions involved.)
– moewe
May 19 at 19:56
@moewe Using pushQED was something I found searching for how to pass arguments to the end part. The space after #1 was from searching the error, removing them doesn't change that. moving popQED behind endscname causes the error to go, but then it prints 'default' and doesn't call endxdefault
– Thorsten Schmitz
May 19 at 20:01
Ah, I see. I don't thinkpopQED
andpushQED
can help you here. Trydeftssavedarg#1
andcsname endxtssavedargendcsname
instead.
– moewe
May 19 at 20:05
expandaftercsname x
expandsx
which is not expandable, so theexpandafter
is doing nothing.
– David Carlisle
May 19 at 20:30
My guess would be that the
popQED
within csname ... endcsname
is a bit too much for LaTeX. I presume popQED
does not expand to simple text, so LaTeX fails to make sense of it as part of a control sequence name. Maybe you just mean csname endx#1endcsnamepopQED
? I'm also not quite sure if the expandafter
s are needed and the trailing space after #1
in csname x#1 endcsname
might be too much. (But this is all speculation without a full example document where I can verify the definitions involved.)– moewe
May 19 at 19:56
My guess would be that the
popQED
within csname ... endcsname
is a bit too much for LaTeX. I presume popQED
does not expand to simple text, so LaTeX fails to make sense of it as part of a control sequence name. Maybe you just mean csname endx#1endcsnamepopQED
? I'm also not quite sure if the expandafter
s are needed and the trailing space after #1
in csname x#1 endcsname
might be too much. (But this is all speculation without a full example document where I can verify the definitions involved.)– moewe
May 19 at 19:56
@moewe Using pushQED was something I found searching for how to pass arguments to the end part. The space after #1 was from searching the error, removing them doesn't change that. moving popQED behind endscname causes the error to go, but then it prints 'default' and doesn't call endxdefault
– Thorsten Schmitz
May 19 at 20:01
@moewe Using pushQED was something I found searching for how to pass arguments to the end part. The space after #1 was from searching the error, removing them doesn't change that. moving popQED behind endscname causes the error to go, but then it prints 'default' and doesn't call endxdefault
– Thorsten Schmitz
May 19 at 20:01
Ah, I see. I don't think
popQED
and pushQED
can help you here. Try deftssavedarg#1
and csname endxtssavedargendcsname
instead.– moewe
May 19 at 20:05
Ah, I see. I don't think
popQED
and pushQED
can help you here. Try deftssavedarg#1
and csname endxtssavedargendcsname
instead.– moewe
May 19 at 20:05
expandaftercsname x
expands x
which is not expandable, so the expandafter
is doing nothing.– David Carlisle
May 19 at 20:30
expandaftercsname x
expands x
which is not expandable, so the expandafter
is doing nothing.– David Carlisle
May 19 at 20:30
add a comment |
2 Answers
2
active
oldest
votes
Try something like
documentclassarticle
usepackage[utf8]inputenc
% make sure tssavedarg is not taken already
newcommand*tssavedarg
newenvironmentmyEnv[1][default]
deftssavedarg#1%
csname x#1endcsname
csname endxtssavedargendcsname
newenvironmentxdefaultXXYY
begindocument
beginmyEnv
A
endmyEnv
enddocument
pushQED
and popQED
are specifically for QED handling in amsmath
and they seem to implement a full QED stack, which you do not need. In particular popQED
does not simply expand to the contents saved with pushQED
, so it does not work within csname ... endcsname
as expected.
In your case it is enough to just save the #1
in a normal macro with def
and then retrieve the macro value by calling it.
Related Why can't the end code of an environment contain an argument?.
The xparse
/LaTeX3 solution would be
usepackagexparse
NewDocumentEnvironmentmyEnvOdefault
csname x#1endcsname
csname endx#1endcsname
or maybe even more expl3
-y
usepackagexparse
ExplSyntaxOn
NewDocumentEnvironmentmyEnvOdefault
use:cx#1
use:cendx#1
ExplSyntaxOff
because xparse
's environments can access the arguments even in the end code.
Thanks for your answer, I will lok into this. Btw could you tell me where you found the doc for pushQED/popQED? I couldn't find one, so I didn't really know, how they worked. Just did what was recommended in a thread I found.
– Thorsten Schmitz
May 19 at 20:29
@ThorstenSchmitz I didn't find a lot about the two. Theamsthm
documentation mentions the two only in a code example. But the source code shows thatpopQED
does not simply expand to the saved test and suggests that the two implement a sort of stack. Where were those commands recommended for the job you had in mind, if I might ask?
– moewe
May 19 at 20:32
mirrors.ctan.org/macros/latex/required/amscls/doc/amsclass.pdf also has a little bit on the commands and their implementation
– moewe
May 19 at 20:37
It was in a thread, but I don't remember where exactly. Didn't think I would need to since there was just a recommendation without further information.
– Thorsten Schmitz
May 20 at 9:40
add a comment |
Let's see how pushQED
and popQED
are defined in amsthm.sty
:
274 DeclareRobustCommandqed%
275 ifmmode mathqed
276 else
277 leavevmodeunskippenalty9999 hboxnobreakhfill
278 quadhboxqedsymbol%
279 fi
280
281 letQED@stack@empty
282 letqed@eltrelax
283 newcommandpushQED[1]%
284 toks@qed@elt#1@temptokenaexpandafterQED@stack%
285 xdefQED@stackthetoks@the@temptokena%
286
287 newcommandpopQED%
288 begingroupletqed@eltpopQED@elt QED@stackrelaxrelaxendgroup
289
290 defpopQED@elt#1#2relax#1gdefQED@stack#2
291 newcommandqedhere%
292 begingroup letmathqedmath@qedhere
293 letqed@eltsetQED@elt QED@stackrelaxrelax endgroup
294
The name clearly shows that this has to do with the typesetting of the QED marker in proofs, so I included the definition of qed
.
There is a “stack”, actually a macro, called QED@stack
, that's initialized to empty.
Suppose we call pushQEDfoo
when the stack is empty. Two scratch token registers are set: first toks@
is set to qed@eltfoo
, then @temptokena
is set to contain the current first level expansion of QED@stack
(in this case, nothing). Next, QED@stack
is redefined to contain the token lists in the two registers; with e-TeX extensions, this could be achieved with the single instruction
xdefQED@stackunexpandedqed@elt#1unexpandedexpandafterQED@stack
So now QED@stack
will expand to qed@eltfoo
. If another pushQEDbar
follows, the expansion would become qed@eltbarqed@eltfoo
. But let's stay with the simple case.
What happens when popQED
is called? The instructions at line 288 are executed, namely
begingroupletqed@eltpopQED@elt QED@stackrelaxrelaxendgroup
The macro qed@elt
(that normally is relax
, see line 282) is set to mean popQED@elt
inside a group and then QED@stackrelaxrelax
is examined. In your case it is
qed@eltfoorelaxrelax
Since the macro qed@elt
has been redefined, this is the same as popQED@eltfoorelaxrelax
and, according to the definition of popQED@elt
,
#1 <- foo
#2 <-
and therefore
foogdefQED@stackrelax
would remain in the main token list (the braces are stripped off by rule of TeX). In case QED@stack
had been qed@eltbarqed@eltfoo
, we'd have
#1 <- bar
#2 <- qed@eltfoo
and bargdefQED@stackqed@eltfoorelax
would be pushed into the main input stream.
Just the fact that the expansion of popQED
begins with begingroup
disqualifies it from being legal inside csname...endcsname
; moreover assignments cannot be performed in that context, so it's a lost battle to begin with.
The double relax
is in case the stack is empty at the time popQED
is called, that is without a matching pushQED
command.
What's the main usage of the system? The standard proof
environment in amsthm.sty
is defined as
432 newenvironmentproof[1][proofname]par
433 pushQEDqed%
434 normalfont topsep6p@@plus6p@relax
435 trivlist
436 item[hskiplabelsep
437 itshape
438 #1@addpunct.]ignorespaces
439 %
440 popQEDendtrivlist@endpefalse
441
The idea is that a subordinate proof environment might define its own tombstone symbol and push it in the stack, so at end environment the right symbol would be used.
Can you use stacks for this purpose? Yes.
documentclassarticle
usepackagexparse
ExplSyntaxOn
NewDocumentCommandnewstackm
seq_new:c g_thorsten_#1_stack_seq
NewDocumentCommandpushmm
% #1 is the stack's name, #2 the item to push
seq_gpush:cn g_thorsten_#1_stack_seq #2
NewDocumentCommandpopmo
% #1 is the stack's name, #2 what you should do with the top item
% reinitialize, in case it has been modified
cs_set_eq:NN __thorsten_stack_exec:n __thorsten_stack_exec_default:n
IfValueT #2
cs_set:Nn __thorsten_stack_exec:n #2
seq_gpop:cNTF g_thorsten_#1_stack_seq l__thorsten_stack_item_tl
% if the stack is not empty
__thorsten_stack_exec:V l__thorsten_stack_item_tl
% if the stack is empty, issue an error
__thorsten_stack_exec:n STACKEMPTYERROR
tl_new:N l__thorsten_stack_item_tl
cs_new_protected:Nn __thorsten_stack_exec_default:n #1
cs_set_eq:NN __thorsten_stack_exec:n __thorsten_stack_exec_default:n
cs_generate_variant:Nn __thorsten_stack_exec:n V
ExplSyntaxOff
newstackenv
newenvironmentmyEnv[1][default]
%
pushenv#1%
csname x#1endcsname
%
popenv[csname endx##1endcsname]%
newenvironmentxdefaultpar startfinishpar
newenvironmentxinnerpar startinnerfinishinnerpar
begindocument
beginmyEnv
beginmyEnv[inner]
endmyEnv
endmyEnv
newstackfoo
pushfooA
pushfooB
pushfooC
popfoo[@@#1@@]
popfoo[??#1??]
popfoo[!!#1!!]
popfoo[---#1---]
enddocument
The push
command takes as arguments the stack's name and the item to push. pop
takes as mandatory argument the stack's name and the optional argument is a template for what to do with the popped item (default is to just deliver it) after removing the item from the top of the stack.
Be careful with spaces in your input: csname x#1 endcsname
is not the same as csname x#1endcsname
.
Since in the last example the pop
operation is called on an empty stack, an error is produced
! Undefined control sequence.
<argument> STACKEMPTYERROR
l.69 popfoo[---#1---]
Thanks for that very detailed explanation. For now I will stick to the xparse package, but I'm sure this will be usefull in the future. At the very least it's a great explanation for pushQED/popQED.
– Thorsten Schmitz
May 20 at 9:39
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f491651%2fcsname-in-newenviroment%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Try something like
documentclassarticle
usepackage[utf8]inputenc
% make sure tssavedarg is not taken already
newcommand*tssavedarg
newenvironmentmyEnv[1][default]
deftssavedarg#1%
csname x#1endcsname
csname endxtssavedargendcsname
newenvironmentxdefaultXXYY
begindocument
beginmyEnv
A
endmyEnv
enddocument
pushQED
and popQED
are specifically for QED handling in amsmath
and they seem to implement a full QED stack, which you do not need. In particular popQED
does not simply expand to the contents saved with pushQED
, so it does not work within csname ... endcsname
as expected.
In your case it is enough to just save the #1
in a normal macro with def
and then retrieve the macro value by calling it.
Related Why can't the end code of an environment contain an argument?.
The xparse
/LaTeX3 solution would be
usepackagexparse
NewDocumentEnvironmentmyEnvOdefault
csname x#1endcsname
csname endx#1endcsname
or maybe even more expl3
-y
usepackagexparse
ExplSyntaxOn
NewDocumentEnvironmentmyEnvOdefault
use:cx#1
use:cendx#1
ExplSyntaxOff
because xparse
's environments can access the arguments even in the end code.
Thanks for your answer, I will lok into this. Btw could you tell me where you found the doc for pushQED/popQED? I couldn't find one, so I didn't really know, how they worked. Just did what was recommended in a thread I found.
– Thorsten Schmitz
May 19 at 20:29
@ThorstenSchmitz I didn't find a lot about the two. Theamsthm
documentation mentions the two only in a code example. But the source code shows thatpopQED
does not simply expand to the saved test and suggests that the two implement a sort of stack. Where were those commands recommended for the job you had in mind, if I might ask?
– moewe
May 19 at 20:32
mirrors.ctan.org/macros/latex/required/amscls/doc/amsclass.pdf also has a little bit on the commands and their implementation
– moewe
May 19 at 20:37
It was in a thread, but I don't remember where exactly. Didn't think I would need to since there was just a recommendation without further information.
– Thorsten Schmitz
May 20 at 9:40
add a comment |
Try something like
documentclassarticle
usepackage[utf8]inputenc
% make sure tssavedarg is not taken already
newcommand*tssavedarg
newenvironmentmyEnv[1][default]
deftssavedarg#1%
csname x#1endcsname
csname endxtssavedargendcsname
newenvironmentxdefaultXXYY
begindocument
beginmyEnv
A
endmyEnv
enddocument
pushQED
and popQED
are specifically for QED handling in amsmath
and they seem to implement a full QED stack, which you do not need. In particular popQED
does not simply expand to the contents saved with pushQED
, so it does not work within csname ... endcsname
as expected.
In your case it is enough to just save the #1
in a normal macro with def
and then retrieve the macro value by calling it.
Related Why can't the end code of an environment contain an argument?.
The xparse
/LaTeX3 solution would be
usepackagexparse
NewDocumentEnvironmentmyEnvOdefault
csname x#1endcsname
csname endx#1endcsname
or maybe even more expl3
-y
usepackagexparse
ExplSyntaxOn
NewDocumentEnvironmentmyEnvOdefault
use:cx#1
use:cendx#1
ExplSyntaxOff
because xparse
's environments can access the arguments even in the end code.
Thanks for your answer, I will lok into this. Btw could you tell me where you found the doc for pushQED/popQED? I couldn't find one, so I didn't really know, how they worked. Just did what was recommended in a thread I found.
– Thorsten Schmitz
May 19 at 20:29
@ThorstenSchmitz I didn't find a lot about the two. Theamsthm
documentation mentions the two only in a code example. But the source code shows thatpopQED
does not simply expand to the saved test and suggests that the two implement a sort of stack. Where were those commands recommended for the job you had in mind, if I might ask?
– moewe
May 19 at 20:32
mirrors.ctan.org/macros/latex/required/amscls/doc/amsclass.pdf also has a little bit on the commands and their implementation
– moewe
May 19 at 20:37
It was in a thread, but I don't remember where exactly. Didn't think I would need to since there was just a recommendation without further information.
– Thorsten Schmitz
May 20 at 9:40
add a comment |
Try something like
documentclassarticle
usepackage[utf8]inputenc
% make sure tssavedarg is not taken already
newcommand*tssavedarg
newenvironmentmyEnv[1][default]
deftssavedarg#1%
csname x#1endcsname
csname endxtssavedargendcsname
newenvironmentxdefaultXXYY
begindocument
beginmyEnv
A
endmyEnv
enddocument
pushQED
and popQED
are specifically for QED handling in amsmath
and they seem to implement a full QED stack, which you do not need. In particular popQED
does not simply expand to the contents saved with pushQED
, so it does not work within csname ... endcsname
as expected.
In your case it is enough to just save the #1
in a normal macro with def
and then retrieve the macro value by calling it.
Related Why can't the end code of an environment contain an argument?.
The xparse
/LaTeX3 solution would be
usepackagexparse
NewDocumentEnvironmentmyEnvOdefault
csname x#1endcsname
csname endx#1endcsname
or maybe even more expl3
-y
usepackagexparse
ExplSyntaxOn
NewDocumentEnvironmentmyEnvOdefault
use:cx#1
use:cendx#1
ExplSyntaxOff
because xparse
's environments can access the arguments even in the end code.
Try something like
documentclassarticle
usepackage[utf8]inputenc
% make sure tssavedarg is not taken already
newcommand*tssavedarg
newenvironmentmyEnv[1][default]
deftssavedarg#1%
csname x#1endcsname
csname endxtssavedargendcsname
newenvironmentxdefaultXXYY
begindocument
beginmyEnv
A
endmyEnv
enddocument
pushQED
and popQED
are specifically for QED handling in amsmath
and they seem to implement a full QED stack, which you do not need. In particular popQED
does not simply expand to the contents saved with pushQED
, so it does not work within csname ... endcsname
as expected.
In your case it is enough to just save the #1
in a normal macro with def
and then retrieve the macro value by calling it.
Related Why can't the end code of an environment contain an argument?.
The xparse
/LaTeX3 solution would be
usepackagexparse
NewDocumentEnvironmentmyEnvOdefault
csname x#1endcsname
csname endx#1endcsname
or maybe even more expl3
-y
usepackagexparse
ExplSyntaxOn
NewDocumentEnvironmentmyEnvOdefault
use:cx#1
use:cendx#1
ExplSyntaxOff
because xparse
's environments can access the arguments even in the end code.
edited May 19 at 20:14
answered May 19 at 20:09
moewemoewe
99.1k10121375
99.1k10121375
Thanks for your answer, I will lok into this. Btw could you tell me where you found the doc for pushQED/popQED? I couldn't find one, so I didn't really know, how they worked. Just did what was recommended in a thread I found.
– Thorsten Schmitz
May 19 at 20:29
@ThorstenSchmitz I didn't find a lot about the two. Theamsthm
documentation mentions the two only in a code example. But the source code shows thatpopQED
does not simply expand to the saved test and suggests that the two implement a sort of stack. Where were those commands recommended for the job you had in mind, if I might ask?
– moewe
May 19 at 20:32
mirrors.ctan.org/macros/latex/required/amscls/doc/amsclass.pdf also has a little bit on the commands and their implementation
– moewe
May 19 at 20:37
It was in a thread, but I don't remember where exactly. Didn't think I would need to since there was just a recommendation without further information.
– Thorsten Schmitz
May 20 at 9:40
add a comment |
Thanks for your answer, I will lok into this. Btw could you tell me where you found the doc for pushQED/popQED? I couldn't find one, so I didn't really know, how they worked. Just did what was recommended in a thread I found.
– Thorsten Schmitz
May 19 at 20:29
@ThorstenSchmitz I didn't find a lot about the two. Theamsthm
documentation mentions the two only in a code example. But the source code shows thatpopQED
does not simply expand to the saved test and suggests that the two implement a sort of stack. Where were those commands recommended for the job you had in mind, if I might ask?
– moewe
May 19 at 20:32
mirrors.ctan.org/macros/latex/required/amscls/doc/amsclass.pdf also has a little bit on the commands and their implementation
– moewe
May 19 at 20:37
It was in a thread, but I don't remember where exactly. Didn't think I would need to since there was just a recommendation without further information.
– Thorsten Schmitz
May 20 at 9:40
Thanks for your answer, I will lok into this. Btw could you tell me where you found the doc for pushQED/popQED? I couldn't find one, so I didn't really know, how they worked. Just did what was recommended in a thread I found.
– Thorsten Schmitz
May 19 at 20:29
Thanks for your answer, I will lok into this. Btw could you tell me where you found the doc for pushQED/popQED? I couldn't find one, so I didn't really know, how they worked. Just did what was recommended in a thread I found.
– Thorsten Schmitz
May 19 at 20:29
@ThorstenSchmitz I didn't find a lot about the two. The
amsthm
documentation mentions the two only in a code example. But the source code shows that popQED
does not simply expand to the saved test and suggests that the two implement a sort of stack. Where were those commands recommended for the job you had in mind, if I might ask?– moewe
May 19 at 20:32
@ThorstenSchmitz I didn't find a lot about the two. The
amsthm
documentation mentions the two only in a code example. But the source code shows that popQED
does not simply expand to the saved test and suggests that the two implement a sort of stack. Where were those commands recommended for the job you had in mind, if I might ask?– moewe
May 19 at 20:32
mirrors.ctan.org/macros/latex/required/amscls/doc/amsclass.pdf also has a little bit on the commands and their implementation
– moewe
May 19 at 20:37
mirrors.ctan.org/macros/latex/required/amscls/doc/amsclass.pdf also has a little bit on the commands and their implementation
– moewe
May 19 at 20:37
It was in a thread, but I don't remember where exactly. Didn't think I would need to since there was just a recommendation without further information.
– Thorsten Schmitz
May 20 at 9:40
It was in a thread, but I don't remember where exactly. Didn't think I would need to since there was just a recommendation without further information.
– Thorsten Schmitz
May 20 at 9:40
add a comment |
Let's see how pushQED
and popQED
are defined in amsthm.sty
:
274 DeclareRobustCommandqed%
275 ifmmode mathqed
276 else
277 leavevmodeunskippenalty9999 hboxnobreakhfill
278 quadhboxqedsymbol%
279 fi
280
281 letQED@stack@empty
282 letqed@eltrelax
283 newcommandpushQED[1]%
284 toks@qed@elt#1@temptokenaexpandafterQED@stack%
285 xdefQED@stackthetoks@the@temptokena%
286
287 newcommandpopQED%
288 begingroupletqed@eltpopQED@elt QED@stackrelaxrelaxendgroup
289
290 defpopQED@elt#1#2relax#1gdefQED@stack#2
291 newcommandqedhere%
292 begingroup letmathqedmath@qedhere
293 letqed@eltsetQED@elt QED@stackrelaxrelax endgroup
294
The name clearly shows that this has to do with the typesetting of the QED marker in proofs, so I included the definition of qed
.
There is a “stack”, actually a macro, called QED@stack
, that's initialized to empty.
Suppose we call pushQEDfoo
when the stack is empty. Two scratch token registers are set: first toks@
is set to qed@eltfoo
, then @temptokena
is set to contain the current first level expansion of QED@stack
(in this case, nothing). Next, QED@stack
is redefined to contain the token lists in the two registers; with e-TeX extensions, this could be achieved with the single instruction
xdefQED@stackunexpandedqed@elt#1unexpandedexpandafterQED@stack
So now QED@stack
will expand to qed@eltfoo
. If another pushQEDbar
follows, the expansion would become qed@eltbarqed@eltfoo
. But let's stay with the simple case.
What happens when popQED
is called? The instructions at line 288 are executed, namely
begingroupletqed@eltpopQED@elt QED@stackrelaxrelaxendgroup
The macro qed@elt
(that normally is relax
, see line 282) is set to mean popQED@elt
inside a group and then QED@stackrelaxrelax
is examined. In your case it is
qed@eltfoorelaxrelax
Since the macro qed@elt
has been redefined, this is the same as popQED@eltfoorelaxrelax
and, according to the definition of popQED@elt
,
#1 <- foo
#2 <-
and therefore
foogdefQED@stackrelax
would remain in the main token list (the braces are stripped off by rule of TeX). In case QED@stack
had been qed@eltbarqed@eltfoo
, we'd have
#1 <- bar
#2 <- qed@eltfoo
and bargdefQED@stackqed@eltfoorelax
would be pushed into the main input stream.
Just the fact that the expansion of popQED
begins with begingroup
disqualifies it from being legal inside csname...endcsname
; moreover assignments cannot be performed in that context, so it's a lost battle to begin with.
The double relax
is in case the stack is empty at the time popQED
is called, that is without a matching pushQED
command.
What's the main usage of the system? The standard proof
environment in amsthm.sty
is defined as
432 newenvironmentproof[1][proofname]par
433 pushQEDqed%
434 normalfont topsep6p@@plus6p@relax
435 trivlist
436 item[hskiplabelsep
437 itshape
438 #1@addpunct.]ignorespaces
439 %
440 popQEDendtrivlist@endpefalse
441
The idea is that a subordinate proof environment might define its own tombstone symbol and push it in the stack, so at end environment the right symbol would be used.
Can you use stacks for this purpose? Yes.
documentclassarticle
usepackagexparse
ExplSyntaxOn
NewDocumentCommandnewstackm
seq_new:c g_thorsten_#1_stack_seq
NewDocumentCommandpushmm
% #1 is the stack's name, #2 the item to push
seq_gpush:cn g_thorsten_#1_stack_seq #2
NewDocumentCommandpopmo
% #1 is the stack's name, #2 what you should do with the top item
% reinitialize, in case it has been modified
cs_set_eq:NN __thorsten_stack_exec:n __thorsten_stack_exec_default:n
IfValueT #2
cs_set:Nn __thorsten_stack_exec:n #2
seq_gpop:cNTF g_thorsten_#1_stack_seq l__thorsten_stack_item_tl
% if the stack is not empty
__thorsten_stack_exec:V l__thorsten_stack_item_tl
% if the stack is empty, issue an error
__thorsten_stack_exec:n STACKEMPTYERROR
tl_new:N l__thorsten_stack_item_tl
cs_new_protected:Nn __thorsten_stack_exec_default:n #1
cs_set_eq:NN __thorsten_stack_exec:n __thorsten_stack_exec_default:n
cs_generate_variant:Nn __thorsten_stack_exec:n V
ExplSyntaxOff
newstackenv
newenvironmentmyEnv[1][default]
%
pushenv#1%
csname x#1endcsname
%
popenv[csname endx##1endcsname]%
newenvironmentxdefaultpar startfinishpar
newenvironmentxinnerpar startinnerfinishinnerpar
begindocument
beginmyEnv
beginmyEnv[inner]
endmyEnv
endmyEnv
newstackfoo
pushfooA
pushfooB
pushfooC
popfoo[@@#1@@]
popfoo[??#1??]
popfoo[!!#1!!]
popfoo[---#1---]
enddocument
The push
command takes as arguments the stack's name and the item to push. pop
takes as mandatory argument the stack's name and the optional argument is a template for what to do with the popped item (default is to just deliver it) after removing the item from the top of the stack.
Be careful with spaces in your input: csname x#1 endcsname
is not the same as csname x#1endcsname
.
Since in the last example the pop
operation is called on an empty stack, an error is produced
! Undefined control sequence.
<argument> STACKEMPTYERROR
l.69 popfoo[---#1---]
Thanks for that very detailed explanation. For now I will stick to the xparse package, but I'm sure this will be usefull in the future. At the very least it's a great explanation for pushQED/popQED.
– Thorsten Schmitz
May 20 at 9:39
add a comment |
Let's see how pushQED
and popQED
are defined in amsthm.sty
:
274 DeclareRobustCommandqed%
275 ifmmode mathqed
276 else
277 leavevmodeunskippenalty9999 hboxnobreakhfill
278 quadhboxqedsymbol%
279 fi
280
281 letQED@stack@empty
282 letqed@eltrelax
283 newcommandpushQED[1]%
284 toks@qed@elt#1@temptokenaexpandafterQED@stack%
285 xdefQED@stackthetoks@the@temptokena%
286
287 newcommandpopQED%
288 begingroupletqed@eltpopQED@elt QED@stackrelaxrelaxendgroup
289
290 defpopQED@elt#1#2relax#1gdefQED@stack#2
291 newcommandqedhere%
292 begingroup letmathqedmath@qedhere
293 letqed@eltsetQED@elt QED@stackrelaxrelax endgroup
294
The name clearly shows that this has to do with the typesetting of the QED marker in proofs, so I included the definition of qed
.
There is a “stack”, actually a macro, called QED@stack
, that's initialized to empty.
Suppose we call pushQEDfoo
when the stack is empty. Two scratch token registers are set: first toks@
is set to qed@eltfoo
, then @temptokena
is set to contain the current first level expansion of QED@stack
(in this case, nothing). Next, QED@stack
is redefined to contain the token lists in the two registers; with e-TeX extensions, this could be achieved with the single instruction
xdefQED@stackunexpandedqed@elt#1unexpandedexpandafterQED@stack
So now QED@stack
will expand to qed@eltfoo
. If another pushQEDbar
follows, the expansion would become qed@eltbarqed@eltfoo
. But let's stay with the simple case.
What happens when popQED
is called? The instructions at line 288 are executed, namely
begingroupletqed@eltpopQED@elt QED@stackrelaxrelaxendgroup
The macro qed@elt
(that normally is relax
, see line 282) is set to mean popQED@elt
inside a group and then QED@stackrelaxrelax
is examined. In your case it is
qed@eltfoorelaxrelax
Since the macro qed@elt
has been redefined, this is the same as popQED@eltfoorelaxrelax
and, according to the definition of popQED@elt
,
#1 <- foo
#2 <-
and therefore
foogdefQED@stackrelax
would remain in the main token list (the braces are stripped off by rule of TeX). In case QED@stack
had been qed@eltbarqed@eltfoo
, we'd have
#1 <- bar
#2 <- qed@eltfoo
and bargdefQED@stackqed@eltfoorelax
would be pushed into the main input stream.
Just the fact that the expansion of popQED
begins with begingroup
disqualifies it from being legal inside csname...endcsname
; moreover assignments cannot be performed in that context, so it's a lost battle to begin with.
The double relax
is in case the stack is empty at the time popQED
is called, that is without a matching pushQED
command.
What's the main usage of the system? The standard proof
environment in amsthm.sty
is defined as
432 newenvironmentproof[1][proofname]par
433 pushQEDqed%
434 normalfont topsep6p@@plus6p@relax
435 trivlist
436 item[hskiplabelsep
437 itshape
438 #1@addpunct.]ignorespaces
439 %
440 popQEDendtrivlist@endpefalse
441
The idea is that a subordinate proof environment might define its own tombstone symbol and push it in the stack, so at end environment the right symbol would be used.
Can you use stacks for this purpose? Yes.
documentclassarticle
usepackagexparse
ExplSyntaxOn
NewDocumentCommandnewstackm
seq_new:c g_thorsten_#1_stack_seq
NewDocumentCommandpushmm
% #1 is the stack's name, #2 the item to push
seq_gpush:cn g_thorsten_#1_stack_seq #2
NewDocumentCommandpopmo
% #1 is the stack's name, #2 what you should do with the top item
% reinitialize, in case it has been modified
cs_set_eq:NN __thorsten_stack_exec:n __thorsten_stack_exec_default:n
IfValueT #2
cs_set:Nn __thorsten_stack_exec:n #2
seq_gpop:cNTF g_thorsten_#1_stack_seq l__thorsten_stack_item_tl
% if the stack is not empty
__thorsten_stack_exec:V l__thorsten_stack_item_tl
% if the stack is empty, issue an error
__thorsten_stack_exec:n STACKEMPTYERROR
tl_new:N l__thorsten_stack_item_tl
cs_new_protected:Nn __thorsten_stack_exec_default:n #1
cs_set_eq:NN __thorsten_stack_exec:n __thorsten_stack_exec_default:n
cs_generate_variant:Nn __thorsten_stack_exec:n V
ExplSyntaxOff
newstackenv
newenvironmentmyEnv[1][default]
%
pushenv#1%
csname x#1endcsname
%
popenv[csname endx##1endcsname]%
newenvironmentxdefaultpar startfinishpar
newenvironmentxinnerpar startinnerfinishinnerpar
begindocument
beginmyEnv
beginmyEnv[inner]
endmyEnv
endmyEnv
newstackfoo
pushfooA
pushfooB
pushfooC
popfoo[@@#1@@]
popfoo[??#1??]
popfoo[!!#1!!]
popfoo[---#1---]
enddocument
The push
command takes as arguments the stack's name and the item to push. pop
takes as mandatory argument the stack's name and the optional argument is a template for what to do with the popped item (default is to just deliver it) after removing the item from the top of the stack.
Be careful with spaces in your input: csname x#1 endcsname
is not the same as csname x#1endcsname
.
Since in the last example the pop
operation is called on an empty stack, an error is produced
! Undefined control sequence.
<argument> STACKEMPTYERROR
l.69 popfoo[---#1---]
Thanks for that very detailed explanation. For now I will stick to the xparse package, but I'm sure this will be usefull in the future. At the very least it's a great explanation for pushQED/popQED.
– Thorsten Schmitz
May 20 at 9:39
add a comment |
Let's see how pushQED
and popQED
are defined in amsthm.sty
:
274 DeclareRobustCommandqed%
275 ifmmode mathqed
276 else
277 leavevmodeunskippenalty9999 hboxnobreakhfill
278 quadhboxqedsymbol%
279 fi
280
281 letQED@stack@empty
282 letqed@eltrelax
283 newcommandpushQED[1]%
284 toks@qed@elt#1@temptokenaexpandafterQED@stack%
285 xdefQED@stackthetoks@the@temptokena%
286
287 newcommandpopQED%
288 begingroupletqed@eltpopQED@elt QED@stackrelaxrelaxendgroup
289
290 defpopQED@elt#1#2relax#1gdefQED@stack#2
291 newcommandqedhere%
292 begingroup letmathqedmath@qedhere
293 letqed@eltsetQED@elt QED@stackrelaxrelax endgroup
294
The name clearly shows that this has to do with the typesetting of the QED marker in proofs, so I included the definition of qed
.
There is a “stack”, actually a macro, called QED@stack
, that's initialized to empty.
Suppose we call pushQEDfoo
when the stack is empty. Two scratch token registers are set: first toks@
is set to qed@eltfoo
, then @temptokena
is set to contain the current first level expansion of QED@stack
(in this case, nothing). Next, QED@stack
is redefined to contain the token lists in the two registers; with e-TeX extensions, this could be achieved with the single instruction
xdefQED@stackunexpandedqed@elt#1unexpandedexpandafterQED@stack
So now QED@stack
will expand to qed@eltfoo
. If another pushQEDbar
follows, the expansion would become qed@eltbarqed@eltfoo
. But let's stay with the simple case.
What happens when popQED
is called? The instructions at line 288 are executed, namely
begingroupletqed@eltpopQED@elt QED@stackrelaxrelaxendgroup
The macro qed@elt
(that normally is relax
, see line 282) is set to mean popQED@elt
inside a group and then QED@stackrelaxrelax
is examined. In your case it is
qed@eltfoorelaxrelax
Since the macro qed@elt
has been redefined, this is the same as popQED@eltfoorelaxrelax
and, according to the definition of popQED@elt
,
#1 <- foo
#2 <-
and therefore
foogdefQED@stackrelax
would remain in the main token list (the braces are stripped off by rule of TeX). In case QED@stack
had been qed@eltbarqed@eltfoo
, we'd have
#1 <- bar
#2 <- qed@eltfoo
and bargdefQED@stackqed@eltfoorelax
would be pushed into the main input stream.
Just the fact that the expansion of popQED
begins with begingroup
disqualifies it from being legal inside csname...endcsname
; moreover assignments cannot be performed in that context, so it's a lost battle to begin with.
The double relax
is in case the stack is empty at the time popQED
is called, that is without a matching pushQED
command.
What's the main usage of the system? The standard proof
environment in amsthm.sty
is defined as
432 newenvironmentproof[1][proofname]par
433 pushQEDqed%
434 normalfont topsep6p@@plus6p@relax
435 trivlist
436 item[hskiplabelsep
437 itshape
438 #1@addpunct.]ignorespaces
439 %
440 popQEDendtrivlist@endpefalse
441
The idea is that a subordinate proof environment might define its own tombstone symbol and push it in the stack, so at end environment the right symbol would be used.
Can you use stacks for this purpose? Yes.
documentclassarticle
usepackagexparse
ExplSyntaxOn
NewDocumentCommandnewstackm
seq_new:c g_thorsten_#1_stack_seq
NewDocumentCommandpushmm
% #1 is the stack's name, #2 the item to push
seq_gpush:cn g_thorsten_#1_stack_seq #2
NewDocumentCommandpopmo
% #1 is the stack's name, #2 what you should do with the top item
% reinitialize, in case it has been modified
cs_set_eq:NN __thorsten_stack_exec:n __thorsten_stack_exec_default:n
IfValueT #2
cs_set:Nn __thorsten_stack_exec:n #2
seq_gpop:cNTF g_thorsten_#1_stack_seq l__thorsten_stack_item_tl
% if the stack is not empty
__thorsten_stack_exec:V l__thorsten_stack_item_tl
% if the stack is empty, issue an error
__thorsten_stack_exec:n STACKEMPTYERROR
tl_new:N l__thorsten_stack_item_tl
cs_new_protected:Nn __thorsten_stack_exec_default:n #1
cs_set_eq:NN __thorsten_stack_exec:n __thorsten_stack_exec_default:n
cs_generate_variant:Nn __thorsten_stack_exec:n V
ExplSyntaxOff
newstackenv
newenvironmentmyEnv[1][default]
%
pushenv#1%
csname x#1endcsname
%
popenv[csname endx##1endcsname]%
newenvironmentxdefaultpar startfinishpar
newenvironmentxinnerpar startinnerfinishinnerpar
begindocument
beginmyEnv
beginmyEnv[inner]
endmyEnv
endmyEnv
newstackfoo
pushfooA
pushfooB
pushfooC
popfoo[@@#1@@]
popfoo[??#1??]
popfoo[!!#1!!]
popfoo[---#1---]
enddocument
The push
command takes as arguments the stack's name and the item to push. pop
takes as mandatory argument the stack's name and the optional argument is a template for what to do with the popped item (default is to just deliver it) after removing the item from the top of the stack.
Be careful with spaces in your input: csname x#1 endcsname
is not the same as csname x#1endcsname
.
Since in the last example the pop
operation is called on an empty stack, an error is produced
! Undefined control sequence.
<argument> STACKEMPTYERROR
l.69 popfoo[---#1---]
Let's see how pushQED
and popQED
are defined in amsthm.sty
:
274 DeclareRobustCommandqed%
275 ifmmode mathqed
276 else
277 leavevmodeunskippenalty9999 hboxnobreakhfill
278 quadhboxqedsymbol%
279 fi
280
281 letQED@stack@empty
282 letqed@eltrelax
283 newcommandpushQED[1]%
284 toks@qed@elt#1@temptokenaexpandafterQED@stack%
285 xdefQED@stackthetoks@the@temptokena%
286
287 newcommandpopQED%
288 begingroupletqed@eltpopQED@elt QED@stackrelaxrelaxendgroup
289
290 defpopQED@elt#1#2relax#1gdefQED@stack#2
291 newcommandqedhere%
292 begingroup letmathqedmath@qedhere
293 letqed@eltsetQED@elt QED@stackrelaxrelax endgroup
294
The name clearly shows that this has to do with the typesetting of the QED marker in proofs, so I included the definition of qed
.
There is a “stack”, actually a macro, called QED@stack
, that's initialized to empty.
Suppose we call pushQEDfoo
when the stack is empty. Two scratch token registers are set: first toks@
is set to qed@eltfoo
, then @temptokena
is set to contain the current first level expansion of QED@stack
(in this case, nothing). Next, QED@stack
is redefined to contain the token lists in the two registers; with e-TeX extensions, this could be achieved with the single instruction
xdefQED@stackunexpandedqed@elt#1unexpandedexpandafterQED@stack
So now QED@stack
will expand to qed@eltfoo
. If another pushQEDbar
follows, the expansion would become qed@eltbarqed@eltfoo
. But let's stay with the simple case.
What happens when popQED
is called? The instructions at line 288 are executed, namely
begingroupletqed@eltpopQED@elt QED@stackrelaxrelaxendgroup
The macro qed@elt
(that normally is relax
, see line 282) is set to mean popQED@elt
inside a group and then QED@stackrelaxrelax
is examined. In your case it is
qed@eltfoorelaxrelax
Since the macro qed@elt
has been redefined, this is the same as popQED@eltfoorelaxrelax
and, according to the definition of popQED@elt
,
#1 <- foo
#2 <-
and therefore
foogdefQED@stackrelax
would remain in the main token list (the braces are stripped off by rule of TeX). In case QED@stack
had been qed@eltbarqed@eltfoo
, we'd have
#1 <- bar
#2 <- qed@eltfoo
and bargdefQED@stackqed@eltfoorelax
would be pushed into the main input stream.
Just the fact that the expansion of popQED
begins with begingroup
disqualifies it from being legal inside csname...endcsname
; moreover assignments cannot be performed in that context, so it's a lost battle to begin with.
The double relax
is in case the stack is empty at the time popQED
is called, that is without a matching pushQED
command.
What's the main usage of the system? The standard proof
environment in amsthm.sty
is defined as
432 newenvironmentproof[1][proofname]par
433 pushQEDqed%
434 normalfont topsep6p@@plus6p@relax
435 trivlist
436 item[hskiplabelsep
437 itshape
438 #1@addpunct.]ignorespaces
439 %
440 popQEDendtrivlist@endpefalse
441
The idea is that a subordinate proof environment might define its own tombstone symbol and push it in the stack, so at end environment the right symbol would be used.
Can you use stacks for this purpose? Yes.
documentclassarticle
usepackagexparse
ExplSyntaxOn
NewDocumentCommandnewstackm
seq_new:c g_thorsten_#1_stack_seq
NewDocumentCommandpushmm
% #1 is the stack's name, #2 the item to push
seq_gpush:cn g_thorsten_#1_stack_seq #2
NewDocumentCommandpopmo
% #1 is the stack's name, #2 what you should do with the top item
% reinitialize, in case it has been modified
cs_set_eq:NN __thorsten_stack_exec:n __thorsten_stack_exec_default:n
IfValueT #2
cs_set:Nn __thorsten_stack_exec:n #2
seq_gpop:cNTF g_thorsten_#1_stack_seq l__thorsten_stack_item_tl
% if the stack is not empty
__thorsten_stack_exec:V l__thorsten_stack_item_tl
% if the stack is empty, issue an error
__thorsten_stack_exec:n STACKEMPTYERROR
tl_new:N l__thorsten_stack_item_tl
cs_new_protected:Nn __thorsten_stack_exec_default:n #1
cs_set_eq:NN __thorsten_stack_exec:n __thorsten_stack_exec_default:n
cs_generate_variant:Nn __thorsten_stack_exec:n V
ExplSyntaxOff
newstackenv
newenvironmentmyEnv[1][default]
%
pushenv#1%
csname x#1endcsname
%
popenv[csname endx##1endcsname]%
newenvironmentxdefaultpar startfinishpar
newenvironmentxinnerpar startinnerfinishinnerpar
begindocument
beginmyEnv
beginmyEnv[inner]
endmyEnv
endmyEnv
newstackfoo
pushfooA
pushfooB
pushfooC
popfoo[@@#1@@]
popfoo[??#1??]
popfoo[!!#1!!]
popfoo[---#1---]
enddocument
The push
command takes as arguments the stack's name and the item to push. pop
takes as mandatory argument the stack's name and the optional argument is a template for what to do with the popped item (default is to just deliver it) after removing the item from the top of the stack.
Be careful with spaces in your input: csname x#1 endcsname
is not the same as csname x#1endcsname
.
Since in the last example the pop
operation is called on an empty stack, an error is produced
! Undefined control sequence.
<argument> STACKEMPTYERROR
l.69 popfoo[---#1---]
edited May 19 at 22:36
answered May 19 at 22:26
egregegreg
744k8919473283
744k8919473283
Thanks for that very detailed explanation. For now I will stick to the xparse package, but I'm sure this will be usefull in the future. At the very least it's a great explanation for pushQED/popQED.
– Thorsten Schmitz
May 20 at 9:39
add a comment |
Thanks for that very detailed explanation. For now I will stick to the xparse package, but I'm sure this will be usefull in the future. At the very least it's a great explanation for pushQED/popQED.
– Thorsten Schmitz
May 20 at 9:39
Thanks for that very detailed explanation. For now I will stick to the xparse package, but I'm sure this will be usefull in the future. At the very least it's a great explanation for pushQED/popQED.
– Thorsten Schmitz
May 20 at 9:39
Thanks for that very detailed explanation. For now I will stick to the xparse package, but I'm sure this will be usefull in the future. At the very least it's a great explanation for pushQED/popQED.
– Thorsten Schmitz
May 20 at 9:39
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f491651%2fcsname-in-newenviroment%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
My guess would be that the
popQED
withincsname ... endcsname
is a bit too much for LaTeX. I presumepopQED
does not expand to simple text, so LaTeX fails to make sense of it as part of a control sequence name. Maybe you just meancsname endx#1endcsnamepopQED
? I'm also not quite sure if theexpandafter
s are needed and the trailing space after#1
incsname x#1 endcsname
might be too much. (But this is all speculation without a full example document where I can verify the definitions involved.)– moewe
May 19 at 19:56
@moewe Using pushQED was something I found searching for how to pass arguments to the end part. The space after #1 was from searching the error, removing them doesn't change that. moving popQED behind endscname causes the error to go, but then it prints 'default' and doesn't call endxdefault
– Thorsten Schmitz
May 19 at 20:01
Ah, I see. I don't think
popQED
andpushQED
can help you here. Trydeftssavedarg#1
andcsname endxtssavedargendcsname
instead.– moewe
May 19 at 20:05
expandaftercsname x
expandsx
which is not expandable, so theexpandafter
is doing nothing.– David Carlisle
May 19 at 20:30