Dynamic Conditional Variablesifthenelse conditional & macroGlobal ConditionalFormatting Strings in...
GPS Rollover on Android Smartphones
What are these boxed doors outside store fronts in New York?
Explain the parameters before and after @ in the treminal
How is it possible to have an ability score that is less than 3?
Is it unprofessional to ask if a job posting on GlassDoor is real?
The use of multiple foreign keys on same column in SQL Server
Today is the Center
Is there really no realistic way for a skeleton monster to move around without magic?
Is the month field really deprecated?
Why Is Death Allowed In the Matrix?
If I cast Expeditious Retreat, can I Dash as a bonus action on the same turn?
I’m planning on buying a laser printer but concerned about the life cycle of toner in the machine
Mathematical cryptic clues
Show that if two triangles built on parallel lines, with equal bases have the same perimeter only if they are congruent.
Why are weather verbs 曇る and 晴れる treated differently in this sentence?
Theorems that impeded progress
How old can references or sources in a thesis be?
Can you tell me why doing scalar multiplication of a point on a Elliptic curve over a finite field gets to a point at infinity?
How to re-create Edward Weson's Pepper No. 30?
How to write a macro that is braces sensitive?
Is it possible to make sharp wind that can cut stuff from afar?
Why not use SQL instead of GraphQL?
Can a Warlock become Neutral Good?
same font throughout bibliography
Dynamic Conditional Variables
ifthenelse conditional & macroGlobal ConditionalFormatting Strings in Dynamic Variables with xstringIfx and end of lineHow to create multi-pass command in a .clsNewcommand with PythonTexProtecting blocks of text and commands, not just one command, from expansionUsing a conditional on a custom defined variableConditional tests on string variables in tikzmath libraryWhat is the correct method for conditional printing of variables?
I'm attempting to create documents of a priori unknown length that is determined by a set of conditions. I'm generating LaTeX variables, including conditional variables, using Python. Within a variables LaTeX file, I have something resembling:
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newififVariableOneCondOne
VariableOneCondOnetrue
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableTwoCondOne
VariableTwoCondOnefalse
Where the number of variables are not known. I loop over each variable and have some text that includes the values dynamically defined by the variables.
foreach n in VariableList{
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}.
}
Where I have defined:
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
How can I define a similar command to take advantage of the conditional variables I have defined above? For example, I tried:
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
using the logic that the macro would replace
inputcondnum{n}{CondOne}
with the following
ifVariableOneCondOne
but that does not seem to work. Any suggestions on how to use these dynamically generated conditional variables?
Here is a minimum example:
documentclass{article}
usepackage{pgffor}
% Command to generate variables
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
% Variable definitions
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newififVariableOneCondOne
VariableOneCondOnetrue
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableTwoCondOne
VariableTwoCondOnefalse
begin{document}
foreach n in VariableList{
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}.
inputcondnum{n}{CondOne} Include this text if true else Include this text if false. fi
}
end{document}
macros conditionals
add a comment |
I'm attempting to create documents of a priori unknown length that is determined by a set of conditions. I'm generating LaTeX variables, including conditional variables, using Python. Within a variables LaTeX file, I have something resembling:
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newififVariableOneCondOne
VariableOneCondOnetrue
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableTwoCondOne
VariableTwoCondOnefalse
Where the number of variables are not known. I loop over each variable and have some text that includes the values dynamically defined by the variables.
foreach n in VariableList{
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}.
}
Where I have defined:
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
How can I define a similar command to take advantage of the conditional variables I have defined above? For example, I tried:
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
using the logic that the macro would replace
inputcondnum{n}{CondOne}
with the following
ifVariableOneCondOne
but that does not seem to work. Any suggestions on how to use these dynamically generated conditional variables?
Here is a minimum example:
documentclass{article}
usepackage{pgffor}
% Command to generate variables
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
% Variable definitions
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newififVariableOneCondOne
VariableOneCondOnetrue
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableTwoCondOne
VariableTwoCondOnefalse
begin{document}
foreach n in VariableList{
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}.
inputcondnum{n}{CondOne} Include this text if true else Include this text if false. fi
}
end{document}
macros conditionals
See above for the test file.
– DrTRD
Nov 22 '17 at 18:45
add a comment |
I'm attempting to create documents of a priori unknown length that is determined by a set of conditions. I'm generating LaTeX variables, including conditional variables, using Python. Within a variables LaTeX file, I have something resembling:
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newififVariableOneCondOne
VariableOneCondOnetrue
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableTwoCondOne
VariableTwoCondOnefalse
Where the number of variables are not known. I loop over each variable and have some text that includes the values dynamically defined by the variables.
foreach n in VariableList{
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}.
}
Where I have defined:
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
How can I define a similar command to take advantage of the conditional variables I have defined above? For example, I tried:
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
using the logic that the macro would replace
inputcondnum{n}{CondOne}
with the following
ifVariableOneCondOne
but that does not seem to work. Any suggestions on how to use these dynamically generated conditional variables?
Here is a minimum example:
documentclass{article}
usepackage{pgffor}
% Command to generate variables
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
% Variable definitions
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newififVariableOneCondOne
VariableOneCondOnetrue
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableTwoCondOne
VariableTwoCondOnefalse
begin{document}
foreach n in VariableList{
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}.
inputcondnum{n}{CondOne} Include this text if true else Include this text if false. fi
}
end{document}
macros conditionals
I'm attempting to create documents of a priori unknown length that is determined by a set of conditions. I'm generating LaTeX variables, including conditional variables, using Python. Within a variables LaTeX file, I have something resembling:
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newififVariableOneCondOne
VariableOneCondOnetrue
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableTwoCondOne
VariableTwoCondOnefalse
Where the number of variables are not known. I loop over each variable and have some text that includes the values dynamically defined by the variables.
foreach n in VariableList{
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}.
}
Where I have defined:
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
How can I define a similar command to take advantage of the conditional variables I have defined above? For example, I tried:
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
using the logic that the macro would replace
inputcondnum{n}{CondOne}
with the following
ifVariableOneCondOne
but that does not seem to work. Any suggestions on how to use these dynamically generated conditional variables?
Here is a minimum example:
documentclass{article}
usepackage{pgffor}
% Command to generate variables
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
% Variable definitions
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newififVariableOneCondOne
VariableOneCondOnetrue
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableTwoCondOne
VariableTwoCondOnefalse
begin{document}
foreach n in VariableList{
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}.
inputcondnum{n}{CondOne} Include this text if true else Include this text if false. fi
}
end{document}
macros conditionals
macros conditionals
edited Nov 22 '17 at 18:44
DrTRD
asked Nov 22 '17 at 18:31
DrTRDDrTRD
1575
1575
See above for the test file.
– DrTRD
Nov 22 '17 at 18:45
add a comment |
See above for the test file.
– DrTRD
Nov 22 '17 at 18:45
See above for the test file.
– DrTRD
Nov 22 '17 at 18:45
See above for the test file.
– DrTRD
Nov 22 '17 at 18:45
add a comment |
2 Answers
2
active
oldest
votes
It's generally best to avoid the issue but you can make it work as
documentclass{article}
usepackage{pgffor}
% Command to generate variables
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
% Variable definitions
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newififVariableOneCondOne
VariableOneCondOnetrue
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableTwoCondOne
VariableTwoCondOnefalse
begin{document}
foreach n in VariableList{
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}.
iftruecsname fiendcsnameinputcondnum{n}{CondOne} Include this text if true else Include this text if false. fi
}
end{document}
the issue is that TeX skips over if....fi constructs but it needs to see if... at the same time as it does not do expansion while skipping over "false" sections.
Note also that the expandafter are not needed in
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
in the first case, because csname expands its content anyway so forcing expansion earlier with expandafter results in the same name being constructed. In the second case the expandafter does nothing at all as i is not expandable.
This solution absolutely works, but if you could define inputcondnum, how would you do it to preserve the same variable definitions in the preamble and minimize the code when calling the variable? In other words, how would you define the command inputcondnum so that it works as iftruecsname fiendcsnameinputcondnum ?
– DrTRD
Nov 22 '17 at 18:57
Up to you, just only changing the line newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
– DrTRD
Nov 22 '17 at 19:08
@jfbu 17 minutes ago I was eating dinner, I added some notes about that, then noticed your comment just now:-)
– David Carlisle
Nov 22 '17 at 19:23
3
@DrTRD if you want to use theif..elsefisyntax I would useifinputnum{n} yeselse nofiwhereinputnumwas defined to be00for cases that should be true and01for cases that you want to be false. (then you don't need anynewif`
– David Carlisle
Nov 22 '17 at 19:25
This suggestion really is parsimonious. Thank you!
– DrTRD
Nov 22 '17 at 19:31
|
show 5 more comments
Resurrecting this old question to leave a somewhat cleaner solution, just for posterity.
If, for whatever reason, you're committed to the csname if...endcsname construct (say, if you need to pass the names of already-defined conditionals), a much cleaner solution than the iftruecsname fiendcsnameinputcondnum... hackery is to simply put the entire if...fi construct inside a macro.
The problem arises when your csname if...endcsname is nested inside another conditional—in this case, a hidden one controlling the foreach loop. To elaborate a little on David's answer, when executing a conditional, TeX does some bookkeeping to track of nested if...fis. If a conditional is false, it skips ahead to the next fi (or next else), but it needs to know which fi to skip to. When the skipped text contains a second if...fi, it takes note, and makes sure to continue past the inner fi and keep skipping ahead to the outer fi. However, it doesn't perform any expansions while it's looking for its fi. As a result, when the inner if... is hidden inside another macro (like csname...endcsname) but the fi is still in plain view, its bookkeeping gets thrown off, and everything goes haywire.
The solution is to make sure the if... and the matching fi are both tucked away inside a macro, making sure one is never seen without the other. In your case, you'd modify the minimal example to something like this (with a little formatting for readability):
documentclass{article}
setlength{parindent}{0pt}setlength{parskip}{10pt} %readability
usepackage{pgffor}
% Command to generate variables
newcommand{inputnum}[2]{csname #1#2endcsname}
newcommand{inputcondnum}[2]{csname if#1#2endcsname}
% Variable definitions
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableOneCondOne
newififVariableTwoCondOne
VariableOneCondOnetrue
VariableTwoCondOnefalse
%COMMAND TO TEST CONDITIONAL AND EXECUTE DESIRED CODE
newcommand{testcondnum}[4]{inputcondnum{#1}{#2} #3 else #4 fi}
begin{document}
%A simple implementation
{bfseries Simple}:
foreach n in VariableList{%
texttt{textbackslash n} is n.\%
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}. \%
testcondnum{n}{CondOne}{Include this text if true.}{Include this text if false.}
}
%If you want vary what's going on inside the conditional,
%re-define a macro on each pass through the loop with the
% relevant code to execute. You'll probably want to define
%it with def here, since def doesn't care about overwriting
%old commands. With newcommand and renewcommand, you'd need
%to worry about using one on the first pass and the other
%on subsequent passes.
%Of course, you could also just keep feeding the "Include
%this..." bits straight into testcondnum, but for more
%complicated code, using macros will probably be easier.
{bfseries Dynamic}:
foreach n in VariableList{
defdothisiftrue{Include this text if n CondOne is true.}
defdothisiffalse{Include this text if n CondOne is false.}
texttt{textbackslash n} is n.\%
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}. \%
testcondnum{n}{CondOne}{dothisiftrue}{dothisiffalse}
}
end{document}
Compiling yields:

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%2f402611%2fdynamic-conditional-variables%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
It's generally best to avoid the issue but you can make it work as
documentclass{article}
usepackage{pgffor}
% Command to generate variables
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
% Variable definitions
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newififVariableOneCondOne
VariableOneCondOnetrue
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableTwoCondOne
VariableTwoCondOnefalse
begin{document}
foreach n in VariableList{
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}.
iftruecsname fiendcsnameinputcondnum{n}{CondOne} Include this text if true else Include this text if false. fi
}
end{document}
the issue is that TeX skips over if....fi constructs but it needs to see if... at the same time as it does not do expansion while skipping over "false" sections.
Note also that the expandafter are not needed in
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
in the first case, because csname expands its content anyway so forcing expansion earlier with expandafter results in the same name being constructed. In the second case the expandafter does nothing at all as i is not expandable.
This solution absolutely works, but if you could define inputcondnum, how would you do it to preserve the same variable definitions in the preamble and minimize the code when calling the variable? In other words, how would you define the command inputcondnum so that it works as iftruecsname fiendcsnameinputcondnum ?
– DrTRD
Nov 22 '17 at 18:57
Up to you, just only changing the line newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
– DrTRD
Nov 22 '17 at 19:08
@jfbu 17 minutes ago I was eating dinner, I added some notes about that, then noticed your comment just now:-)
– David Carlisle
Nov 22 '17 at 19:23
3
@DrTRD if you want to use theif..elsefisyntax I would useifinputnum{n} yeselse nofiwhereinputnumwas defined to be00for cases that should be true and01for cases that you want to be false. (then you don't need anynewif`
– David Carlisle
Nov 22 '17 at 19:25
This suggestion really is parsimonious. Thank you!
– DrTRD
Nov 22 '17 at 19:31
|
show 5 more comments
It's generally best to avoid the issue but you can make it work as
documentclass{article}
usepackage{pgffor}
% Command to generate variables
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
% Variable definitions
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newififVariableOneCondOne
VariableOneCondOnetrue
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableTwoCondOne
VariableTwoCondOnefalse
begin{document}
foreach n in VariableList{
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}.
iftruecsname fiendcsnameinputcondnum{n}{CondOne} Include this text if true else Include this text if false. fi
}
end{document}
the issue is that TeX skips over if....fi constructs but it needs to see if... at the same time as it does not do expansion while skipping over "false" sections.
Note also that the expandafter are not needed in
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
in the first case, because csname expands its content anyway so forcing expansion earlier with expandafter results in the same name being constructed. In the second case the expandafter does nothing at all as i is not expandable.
This solution absolutely works, but if you could define inputcondnum, how would you do it to preserve the same variable definitions in the preamble and minimize the code when calling the variable? In other words, how would you define the command inputcondnum so that it works as iftruecsname fiendcsnameinputcondnum ?
– DrTRD
Nov 22 '17 at 18:57
Up to you, just only changing the line newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
– DrTRD
Nov 22 '17 at 19:08
@jfbu 17 minutes ago I was eating dinner, I added some notes about that, then noticed your comment just now:-)
– David Carlisle
Nov 22 '17 at 19:23
3
@DrTRD if you want to use theif..elsefisyntax I would useifinputnum{n} yeselse nofiwhereinputnumwas defined to be00for cases that should be true and01for cases that you want to be false. (then you don't need anynewif`
– David Carlisle
Nov 22 '17 at 19:25
This suggestion really is parsimonious. Thank you!
– DrTRD
Nov 22 '17 at 19:31
|
show 5 more comments
It's generally best to avoid the issue but you can make it work as
documentclass{article}
usepackage{pgffor}
% Command to generate variables
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
% Variable definitions
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newififVariableOneCondOne
VariableOneCondOnetrue
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableTwoCondOne
VariableTwoCondOnefalse
begin{document}
foreach n in VariableList{
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}.
iftruecsname fiendcsnameinputcondnum{n}{CondOne} Include this text if true else Include this text if false. fi
}
end{document}
the issue is that TeX skips over if....fi constructs but it needs to see if... at the same time as it does not do expansion while skipping over "false" sections.
Note also that the expandafter are not needed in
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
in the first case, because csname expands its content anyway so forcing expansion earlier with expandafter results in the same name being constructed. In the second case the expandafter does nothing at all as i is not expandable.
It's generally best to avoid the issue but you can make it work as
documentclass{article}
usepackage{pgffor}
% Command to generate variables
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
% Variable definitions
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newififVariableOneCondOne
VariableOneCondOnetrue
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableTwoCondOne
VariableTwoCondOnefalse
begin{document}
foreach n in VariableList{
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}.
iftruecsname fiendcsnameinputcondnum{n}{CondOne} Include this text if true else Include this text if false. fi
}
end{document}
the issue is that TeX skips over if....fi constructs but it needs to see if... at the same time as it does not do expansion while skipping over "false" sections.
Note also that the expandafter are not needed in
newcommand{inputnum}[2]{expandaftercsname #1#2endcsname}
newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
in the first case, because csname expands its content anyway so forcing expansion earlier with expandafter results in the same name being constructed. In the second case the expandafter does nothing at all as i is not expandable.
edited Nov 22 '17 at 19:20
answered Nov 22 '17 at 18:51
David CarlisleDavid Carlisle
498k4111441893
498k4111441893
This solution absolutely works, but if you could define inputcondnum, how would you do it to preserve the same variable definitions in the preamble and minimize the code when calling the variable? In other words, how would you define the command inputcondnum so that it works as iftruecsname fiendcsnameinputcondnum ?
– DrTRD
Nov 22 '17 at 18:57
Up to you, just only changing the line newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
– DrTRD
Nov 22 '17 at 19:08
@jfbu 17 minutes ago I was eating dinner, I added some notes about that, then noticed your comment just now:-)
– David Carlisle
Nov 22 '17 at 19:23
3
@DrTRD if you want to use theif..elsefisyntax I would useifinputnum{n} yeselse nofiwhereinputnumwas defined to be00for cases that should be true and01for cases that you want to be false. (then you don't need anynewif`
– David Carlisle
Nov 22 '17 at 19:25
This suggestion really is parsimonious. Thank you!
– DrTRD
Nov 22 '17 at 19:31
|
show 5 more comments
This solution absolutely works, but if you could define inputcondnum, how would you do it to preserve the same variable definitions in the preamble and minimize the code when calling the variable? In other words, how would you define the command inputcondnum so that it works as iftruecsname fiendcsnameinputcondnum ?
– DrTRD
Nov 22 '17 at 18:57
Up to you, just only changing the line newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
– DrTRD
Nov 22 '17 at 19:08
@jfbu 17 minutes ago I was eating dinner, I added some notes about that, then noticed your comment just now:-)
– David Carlisle
Nov 22 '17 at 19:23
3
@DrTRD if you want to use theif..elsefisyntax I would useifinputnum{n} yeselse nofiwhereinputnumwas defined to be00for cases that should be true and01for cases that you want to be false. (then you don't need anynewif`
– David Carlisle
Nov 22 '17 at 19:25
This suggestion really is parsimonious. Thank you!
– DrTRD
Nov 22 '17 at 19:31
This solution absolutely works, but if you could define inputcondnum, how would you do it to preserve the same variable definitions in the preamble and minimize the code when calling the variable? In other words, how would you define the command inputcondnum so that it works as iftruecsname fiendcsnameinputcondnum ?
– DrTRD
Nov 22 '17 at 18:57
This solution absolutely works, but if you could define inputcondnum, how would you do it to preserve the same variable definitions in the preamble and minimize the code when calling the variable? In other words, how would you define the command inputcondnum so that it works as iftruecsname fiendcsnameinputcondnum ?
– DrTRD
Nov 22 '17 at 18:57
Up to you, just only changing the line newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
– DrTRD
Nov 22 '17 at 19:08
Up to you, just only changing the line newcommand{inputcondnum}[2]{expandaftercsname if#1#2endcsname}
– DrTRD
Nov 22 '17 at 19:08
@jfbu 17 minutes ago I was eating dinner, I added some notes about that, then noticed your comment just now:-)
– David Carlisle
Nov 22 '17 at 19:23
@jfbu 17 minutes ago I was eating dinner, I added some notes about that, then noticed your comment just now:-)
– David Carlisle
Nov 22 '17 at 19:23
3
3
@DrTRD if you want to use the
if..elsefi syntax I would use ifinputnum{n} yeselse nofi where inputnum was defined to be 00 for cases that should be true and 01 for cases that you want to be false. (then you don't need any newif`– David Carlisle
Nov 22 '17 at 19:25
@DrTRD if you want to use the
if..elsefi syntax I would use ifinputnum{n} yeselse nofi where inputnum was defined to be 00 for cases that should be true and 01 for cases that you want to be false. (then you don't need any newif`– David Carlisle
Nov 22 '17 at 19:25
This suggestion really is parsimonious. Thank you!
– DrTRD
Nov 22 '17 at 19:31
This suggestion really is parsimonious. Thank you!
– DrTRD
Nov 22 '17 at 19:31
|
show 5 more comments
Resurrecting this old question to leave a somewhat cleaner solution, just for posterity.
If, for whatever reason, you're committed to the csname if...endcsname construct (say, if you need to pass the names of already-defined conditionals), a much cleaner solution than the iftruecsname fiendcsnameinputcondnum... hackery is to simply put the entire if...fi construct inside a macro.
The problem arises when your csname if...endcsname is nested inside another conditional—in this case, a hidden one controlling the foreach loop. To elaborate a little on David's answer, when executing a conditional, TeX does some bookkeeping to track of nested if...fis. If a conditional is false, it skips ahead to the next fi (or next else), but it needs to know which fi to skip to. When the skipped text contains a second if...fi, it takes note, and makes sure to continue past the inner fi and keep skipping ahead to the outer fi. However, it doesn't perform any expansions while it's looking for its fi. As a result, when the inner if... is hidden inside another macro (like csname...endcsname) but the fi is still in plain view, its bookkeeping gets thrown off, and everything goes haywire.
The solution is to make sure the if... and the matching fi are both tucked away inside a macro, making sure one is never seen without the other. In your case, you'd modify the minimal example to something like this (with a little formatting for readability):
documentclass{article}
setlength{parindent}{0pt}setlength{parskip}{10pt} %readability
usepackage{pgffor}
% Command to generate variables
newcommand{inputnum}[2]{csname #1#2endcsname}
newcommand{inputcondnum}[2]{csname if#1#2endcsname}
% Variable definitions
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableOneCondOne
newififVariableTwoCondOne
VariableOneCondOnetrue
VariableTwoCondOnefalse
%COMMAND TO TEST CONDITIONAL AND EXECUTE DESIRED CODE
newcommand{testcondnum}[4]{inputcondnum{#1}{#2} #3 else #4 fi}
begin{document}
%A simple implementation
{bfseries Simple}:
foreach n in VariableList{%
texttt{textbackslash n} is n.\%
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}. \%
testcondnum{n}{CondOne}{Include this text if true.}{Include this text if false.}
}
%If you want vary what's going on inside the conditional,
%re-define a macro on each pass through the loop with the
% relevant code to execute. You'll probably want to define
%it with def here, since def doesn't care about overwriting
%old commands. With newcommand and renewcommand, you'd need
%to worry about using one on the first pass and the other
%on subsequent passes.
%Of course, you could also just keep feeding the "Include
%this..." bits straight into testcondnum, but for more
%complicated code, using macros will probably be easier.
{bfseries Dynamic}:
foreach n in VariableList{
defdothisiftrue{Include this text if n CondOne is true.}
defdothisiffalse{Include this text if n CondOne is false.}
texttt{textbackslash n} is n.\%
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}. \%
testcondnum{n}{CondOne}{dothisiftrue}{dothisiffalse}
}
end{document}
Compiling yields:

add a comment |
Resurrecting this old question to leave a somewhat cleaner solution, just for posterity.
If, for whatever reason, you're committed to the csname if...endcsname construct (say, if you need to pass the names of already-defined conditionals), a much cleaner solution than the iftruecsname fiendcsnameinputcondnum... hackery is to simply put the entire if...fi construct inside a macro.
The problem arises when your csname if...endcsname is nested inside another conditional—in this case, a hidden one controlling the foreach loop. To elaborate a little on David's answer, when executing a conditional, TeX does some bookkeeping to track of nested if...fis. If a conditional is false, it skips ahead to the next fi (or next else), but it needs to know which fi to skip to. When the skipped text contains a second if...fi, it takes note, and makes sure to continue past the inner fi and keep skipping ahead to the outer fi. However, it doesn't perform any expansions while it's looking for its fi. As a result, when the inner if... is hidden inside another macro (like csname...endcsname) but the fi is still in plain view, its bookkeeping gets thrown off, and everything goes haywire.
The solution is to make sure the if... and the matching fi are both tucked away inside a macro, making sure one is never seen without the other. In your case, you'd modify the minimal example to something like this (with a little formatting for readability):
documentclass{article}
setlength{parindent}{0pt}setlength{parskip}{10pt} %readability
usepackage{pgffor}
% Command to generate variables
newcommand{inputnum}[2]{csname #1#2endcsname}
newcommand{inputcondnum}[2]{csname if#1#2endcsname}
% Variable definitions
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableOneCondOne
newififVariableTwoCondOne
VariableOneCondOnetrue
VariableTwoCondOnefalse
%COMMAND TO TEST CONDITIONAL AND EXECUTE DESIRED CODE
newcommand{testcondnum}[4]{inputcondnum{#1}{#2} #3 else #4 fi}
begin{document}
%A simple implementation
{bfseries Simple}:
foreach n in VariableList{%
texttt{textbackslash n} is n.\%
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}. \%
testcondnum{n}{CondOne}{Include this text if true.}{Include this text if false.}
}
%If you want vary what's going on inside the conditional,
%re-define a macro on each pass through the loop with the
% relevant code to execute. You'll probably want to define
%it with def here, since def doesn't care about overwriting
%old commands. With newcommand and renewcommand, you'd need
%to worry about using one on the first pass and the other
%on subsequent passes.
%Of course, you could also just keep feeding the "Include
%this..." bits straight into testcondnum, but for more
%complicated code, using macros will probably be easier.
{bfseries Dynamic}:
foreach n in VariableList{
defdothisiftrue{Include this text if n CondOne is true.}
defdothisiffalse{Include this text if n CondOne is false.}
texttt{textbackslash n} is n.\%
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}. \%
testcondnum{n}{CondOne}{dothisiftrue}{dothisiffalse}
}
end{document}
Compiling yields:

add a comment |
Resurrecting this old question to leave a somewhat cleaner solution, just for posterity.
If, for whatever reason, you're committed to the csname if...endcsname construct (say, if you need to pass the names of already-defined conditionals), a much cleaner solution than the iftruecsname fiendcsnameinputcondnum... hackery is to simply put the entire if...fi construct inside a macro.
The problem arises when your csname if...endcsname is nested inside another conditional—in this case, a hidden one controlling the foreach loop. To elaborate a little on David's answer, when executing a conditional, TeX does some bookkeeping to track of nested if...fis. If a conditional is false, it skips ahead to the next fi (or next else), but it needs to know which fi to skip to. When the skipped text contains a second if...fi, it takes note, and makes sure to continue past the inner fi and keep skipping ahead to the outer fi. However, it doesn't perform any expansions while it's looking for its fi. As a result, when the inner if... is hidden inside another macro (like csname...endcsname) but the fi is still in plain view, its bookkeeping gets thrown off, and everything goes haywire.
The solution is to make sure the if... and the matching fi are both tucked away inside a macro, making sure one is never seen without the other. In your case, you'd modify the minimal example to something like this (with a little formatting for readability):
documentclass{article}
setlength{parindent}{0pt}setlength{parskip}{10pt} %readability
usepackage{pgffor}
% Command to generate variables
newcommand{inputnum}[2]{csname #1#2endcsname}
newcommand{inputcondnum}[2]{csname if#1#2endcsname}
% Variable definitions
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableOneCondOne
newififVariableTwoCondOne
VariableOneCondOnetrue
VariableTwoCondOnefalse
%COMMAND TO TEST CONDITIONAL AND EXECUTE DESIRED CODE
newcommand{testcondnum}[4]{inputcondnum{#1}{#2} #3 else #4 fi}
begin{document}
%A simple implementation
{bfseries Simple}:
foreach n in VariableList{%
texttt{textbackslash n} is n.\%
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}. \%
testcondnum{n}{CondOne}{Include this text if true.}{Include this text if false.}
}
%If you want vary what's going on inside the conditional,
%re-define a macro on each pass through the loop with the
% relevant code to execute. You'll probably want to define
%it with def here, since def doesn't care about overwriting
%old commands. With newcommand and renewcommand, you'd need
%to worry about using one on the first pass and the other
%on subsequent passes.
%Of course, you could also just keep feeding the "Include
%this..." bits straight into testcondnum, but for more
%complicated code, using macros will probably be easier.
{bfseries Dynamic}:
foreach n in VariableList{
defdothisiftrue{Include this text if n CondOne is true.}
defdothisiffalse{Include this text if n CondOne is false.}
texttt{textbackslash n} is n.\%
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}. \%
testcondnum{n}{CondOne}{dothisiftrue}{dothisiffalse}
}
end{document}
Compiling yields:

Resurrecting this old question to leave a somewhat cleaner solution, just for posterity.
If, for whatever reason, you're committed to the csname if...endcsname construct (say, if you need to pass the names of already-defined conditionals), a much cleaner solution than the iftruecsname fiendcsnameinputcondnum... hackery is to simply put the entire if...fi construct inside a macro.
The problem arises when your csname if...endcsname is nested inside another conditional—in this case, a hidden one controlling the foreach loop. To elaborate a little on David's answer, when executing a conditional, TeX does some bookkeeping to track of nested if...fis. If a conditional is false, it skips ahead to the next fi (or next else), but it needs to know which fi to skip to. When the skipped text contains a second if...fi, it takes note, and makes sure to continue past the inner fi and keep skipping ahead to the outer fi. However, it doesn't perform any expansions while it's looking for its fi. As a result, when the inner if... is hidden inside another macro (like csname...endcsname) but the fi is still in plain view, its bookkeeping gets thrown off, and everything goes haywire.
The solution is to make sure the if... and the matching fi are both tucked away inside a macro, making sure one is never seen without the other. In your case, you'd modify the minimal example to something like this (with a little formatting for readability):
documentclass{article}
setlength{parindent}{0pt}setlength{parskip}{10pt} %readability
usepackage{pgffor}
% Command to generate variables
newcommand{inputnum}[2]{csname #1#2endcsname}
newcommand{inputcondnum}[2]{csname if#1#2endcsname}
% Variable definitions
newcommand{VariableList}{VariableOne,VariableTwo}
newcommand{VariableOneSubOne}{SomeValueOne}
newcommand{VariableOneSubTwo}{SomeOtherValueOne}
newcommand{VariableTwoSubOne}{SomeValueTwo}
newcommand{VariableTwoSubTwo}{SomeOtherValueTwo}
newififVariableOneCondOne
newififVariableTwoCondOne
VariableOneCondOnetrue
VariableTwoCondOnefalse
%COMMAND TO TEST CONDITIONAL AND EXECUTE DESIRED CODE
newcommand{testcondnum}[4]{inputcondnum{#1}{#2} #3 else #4 fi}
begin{document}
%A simple implementation
{bfseries Simple}:
foreach n in VariableList{%
texttt{textbackslash n} is n.\%
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}. \%
testcondnum{n}{CondOne}{Include this text if true.}{Include this text if false.}
}
%If you want vary what's going on inside the conditional,
%re-define a macro on each pass through the loop with the
% relevant code to execute. You'll probably want to define
%it with def here, since def doesn't care about overwriting
%old commands. With newcommand and renewcommand, you'd need
%to worry about using one on the first pass and the other
%on subsequent passes.
%Of course, you could also just keep feeding the "Include
%this..." bits straight into testcondnum, but for more
%complicated code, using macros will probably be easier.
{bfseries Dynamic}:
foreach n in VariableList{
defdothisiftrue{Include this text if n CondOne is true.}
defdothisiffalse{Include this text if n CondOne is false.}
texttt{textbackslash n} is n.\%
Here is some text with inputnum{n}{SubOne} and inputnum{n}{SubTwo}. \%
testcondnum{n}{CondOne}{dothisiftrue}{dothisiffalse}
}
end{document}
Compiling yields:

answered 8 hours ago
TheMacTheMac
655
655
add a comment |
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%2f402611%2fdynamic-conditional-variables%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
See above for the test file.
– DrTRD
Nov 22 '17 at 18:45