csname in newenviromentWhy can't the end code of an environment contain an argument?How to include origin in problem statementSetup a newenviroment for figure with includegraphics and captionCompiler Error when Creating a Macro/EnvironmentDefinition of a macro with multiple arguments and usage of csname

Adding two lambda-functions in C++

Movie where a boy is transported into the future by an alien spaceship

Sharing one invocation list between multiple events on the same object in C#

Can you `= delete` a templated function on a second declaration?

In this example, which path would a monster affected by the Dissonant Whispers spell take?

What risks are there when you clear your cookies instead of logging off?

Will TSA allow me to carry a Continuous Positive Airway Pressure (CPAP)/sleep apnea device?

Completing the square to find if quadratic form is positive definite.

Their answer is discrete, mine is continuous. They baited me into the wrong answer. I have a P Exam question

Implement Homestuck's Catenative Doomsday Dice Cascader

What happened to all the nuclear material being smuggled after the fall of the USSR?

PC video game involving floating islands doing aerial combat

How could a government be implemented in a virtual reality?

Who operates delivery flights for commercial airlines?

How to supress loops in a digraph?

Is it legal in the UK for politicians to lie to the public for political gain?

Is it possible for people to live in the eye of a permanent hypercane?

Smooth switching between 12v batteries, with toggle switch

Does an ice chest packed full of frozen food need ice? 18 day Grand Canyon trip

Traffic law UK, pedestrians

What happens if you do emergency landing on a US base in middle of the ocean?

How bad would a partial hash leak be, realistically?

Is there any word or phrase for negative bearing?

Does the growth of home value benefit from compound interest?



csname in newenviroment


Why can't the end code of an environment contain an argument?How to include origin in problem statementSetup a newenviroment for figure with includegraphics and captionCompiler Error when Creating a Macro/EnvironmentDefinition of a macro with multiple arguments and usage of csname













2















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?










share|improve this question
























  • 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 expandafters 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












  • 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















2















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?










share|improve this question
























  • 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 expandafters 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












  • 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













2












2








2








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?










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 19 at 19:58







Thorsten Schmitz

















asked May 19 at 19:50









Thorsten SchmitzThorsten Schmitz

112




112












  • 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 expandafters 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












  • 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

















  • 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 expandafters 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












  • 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
















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 expandafters 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 expandafters 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










2 Answers
2






active

oldest

votes


















4














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.






share|improve this answer

























  • 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












  • 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


















4














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.



enter image description here



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---]





share|improve this answer

























  • 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











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%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









4














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.






share|improve this answer

























  • 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












  • 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















4














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.






share|improve this answer

























  • 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












  • 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













4












4








4







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.






share|improve this answer















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.







share|improve this answer














share|improve this answer



share|improve this answer








edited May 19 at 20:14

























answered May 19 at 20:09









moewemoewe

99.3k10121378




99.3k10121378












  • 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












  • 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











  • @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











  • 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











4














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.



enter image description here



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---]





share|improve this answer

























  • 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















4














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.



enter image description here



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---]





share|improve this answer

























  • 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













4












4








4







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.



enter image description here



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---]





share|improve this answer















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.



enter image description here



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---]






share|improve this answer














share|improve this answer



share|improve this answer








edited May 19 at 22:36

























answered May 19 at 22:26









egregegreg

745k8919513291




745k8919513291












  • 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





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

















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.




draft saved


draft discarded














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





















































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

Club Baloncesto Breogán Índice Historia | Pavillón | Nome | O Breogán na cultura popular | Xogadores | Adestradores | Presidentes | Palmarés | Historial | Líderes | Notas | Véxase tamén | Menú de navegacióncbbreogan.galCadroGuía oficial da ACB 2009-10, páxina 201Guía oficial ACB 1992, páxina 183. Editorial DB.É de 6.500 espectadores sentados axeitándose á última normativa"Estudiantes Junior, entre as mellores canteiras"o orixinalHemeroteca El Mundo Deportivo, 16 setembro de 1970, páxina 12Historia do BreogánAlfredo Pérez, o último canoneiroHistoria C.B. BreogánHemeroteca de El Mundo DeportivoJimmy Wright, norteamericano do Breogán deixará Lugo por ameazas de morteResultados de Breogán en 1986-87Resultados de Breogán en 1990-91Ficha de Velimir Perasović en acb.comResultados de Breogán en 1994-95Breogán arrasa al Barça. "El Mundo Deportivo", 27 de setembro de 1999, páxina 58CB Breogán - FC BarcelonaA FEB invita a participar nunha nova Liga EuropeaCharlie Bell na prensa estatalMáximos anotadores 2005Tempada 2005-06 : Tódolos Xogadores da Xornada""Non quero pensar nunha man negra, mais pregúntome que está a pasar""o orixinalRaúl López, orgulloso dos xogadores, presume da boa saúde económica do BreogánJulio González confirma que cesa como presidente del BreogánHomenaxe a Lisardo GómezA tempada do rexurdimento celesteEntrevista a Lisardo GómezEl COB dinamita el Pazo para forzar el quinto (69-73)Cafés Candelas, patrocinador del CB Breogán"Suso Lázare, novo presidente do Breogán"o orixinalCafés Candelas Breogán firma el mayor triunfo de la historiaEl Breogán realizará 17 homenajes por su cincuenta aniversario"O Breogán honra ao seu fundador e primeiro presidente"o orixinalMiguel Giao recibiu a homenaxe do PazoHomenaxe aos primeiros gladiadores celestesO home que nos amosa como ver o Breo co corazónTita Franco será homenaxeada polos #50anosdeBreoJulio Vila recibirá unha homenaxe in memoriam polos #50anosdeBreo"O Breogán homenaxeará aos seus aboados máis veteráns"Pechada ovación a «Capi» Sanmartín e Ricardo «Corazón de González»Homenaxe por décadas de informaciónPaco García volve ao Pazo con motivo do 50 aniversario"Resultados y clasificaciones""O Cafés Candelas Breogán, campión da Copa Princesa""O Cafés Candelas Breogán, equipo ACB"C.B. Breogán"Proxecto social"o orixinal"Centros asociados"o orixinalFicha en imdb.comMario Camus trata la recuperación del amor en 'La vieja música', su última película"Páxina web oficial""Club Baloncesto Breogán""C. B. Breogán S.A.D."eehttp://www.fegaba.com

Vilaño, A Laracha Índice Patrimonio | Lugares e parroquias | Véxase tamén | Menú de navegación43°14′52″N 8°36′03″O / 43.24775, -8.60070

Cegueira Índice Epidemioloxía | Deficiencia visual | Tipos de cegueira | Principais causas de cegueira | Tratamento | Técnicas de adaptación e axudas | Vida dos cegos | Primeiros auxilios | Crenzas respecto das persoas cegas | Crenzas das persoas cegas | O neno deficiente visual | Aspectos psicolóxicos da cegueira | Notas | Véxase tamén | Menú de navegación54.054.154.436928256blindnessDicionario da Real Academia GalegaPortal das Palabras"International Standards: Visual Standards — Aspects and Ranges of Vision Loss with Emphasis on Population Surveys.""Visual impairment and blindness""Presentan un plan para previr a cegueira"o orixinalACCDV Associació Catalana de Cecs i Disminuïts Visuals - PMFTrachoma"Effect of gene therapy on visual function in Leber's congenital amaurosis"1844137110.1056/NEJMoa0802268Cans guía - os mellores amigos dos cegosArquivadoEscola de cans guía para cegos en Mortágua, PortugalArquivado"Tecnología para ciegos y deficientes visuales. Recopilación de recursos gratuitos en la Red""Colorino""‘COL.diesis’, escuchar los sonidos del color""COL.diesis: Transforming Colour into Melody and Implementing the Result in a Colour Sensor Device"o orixinal"Sistema de desarrollo de sinestesia color-sonido para invidentes utilizando un protocolo de audio""Enseñanza táctil - geometría y color. Juegos didácticos para niños ciegos y videntes""Sistema Constanz"L'ocupació laboral dels cecs a l'Estat espanyol està pràcticament equiparada a la de les persones amb visió, entrevista amb Pedro ZuritaONCE (Organización Nacional de Cegos de España)Prevención da cegueiraDescrición de deficiencias visuais (Disc@pnet)Braillín, un boneco atractivo para calquera neno, con ou sen discapacidade, que permite familiarizarse co sistema de escritura e lectura brailleAxudas Técnicas36838ID00897494007150-90057129528256DOID:1432HP:0000618D001766C10.597.751.941.162C97109C0155020